meaning of the title
Sol
Don't ask me why I sent it twice just to cheat traffic
The line tree method of this question is very wonderful
First of all, an obvious conclusion is that the position \ (i \) can be seen only if \ (\ frac < \ frac , K < i \)
Consider maintaining the visible points of the interval \ ([l, r] \).
Because there is only a single point of modification, you only need to consider how to merge two intervals
Maintain the maximum value of \ (\ frac \), and set it to \ (mx \)
First, the left child's answer can be added directly, considering the left child's contribution to the right child. If \ (MX > MX \), then the right child's answer is 0.
Otherwise, consider the contribution of the right child's left child. If \ (MX > MX \), directly add the contribution of the right child's right child under the influence of the right child's left child (difference), recurse the right child's left child. Otherwise, the contribution of left child is 0, recursive right child
In fact, it's still good to write, complexity \ (O(nlog^2n) \)
#include<bits/stdc++.h> using namespace std; const int MAXN = 1e6 + 10; inline int read() { char c = getchar(); int x = 0, f = 1; while(c < '0' || c > '9') while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar(); return x * f; } int N, M, a[MAXN]; int sum[MAXN], ls[MAXN], rs[MAXN], ll[MAXN], rr[MAXN], tot, root; double mx[MAXN]; int find(double lim, int k) { if(ll[k] == rr[k]) return mx[k] > lim; int mid = ll[k] + rr[k] >> 1; if(mx[ls[k]] > lim) return sum[k] - sum[ls[k]] + find(lim, ls[k]); else return find(lim, rs[k]); } void update(int k) { sum[k] = sum[ls[k]]; mx[k] = max(mx[ls[k]], mx[rs[k]]); if(mx[ls[k]] > mx[rs[k]]) return ; sum[k] += find(mx[ls[k]], rs[k]); } void Modify(int &k, int l, int r, int p, double v) { if(!k) k = ++tot, ll[k] = l, rr[k] = r; if(l == r) int mid = l + r >> 1; if(p <= mid) Modify(ls[k], l, mid, p, v); else Modify(rs[k], mid + 1, r, p, v); update(k); } signed main() { N = read(); M = read(); for(int i = 1; i <= M; i++) { int x = read(), y = read(); Modify(root, 1, N, x, (double) y / x); printf("%d\n", sum[root]); } return 0; } /* 3 4 2 4 3 6 1 1000000000 1 1 */