P4198 楼房重建 题解
考虑斜率,我们需要求出以 $1$ 开始的严格上升序列的长度。
考虑维护区间最大值和答案。合并两个区间需要在右区间二分出一个最小的 $j$ 满足 $k_j > \max_{l \le i \le mid} k_i$,然后拼在一起。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 500;
typedef double dl;
dl mx[N << 2];
int n, m;
int ans[N << 2];
#define lc k << 1
#define rc lc | 1
#define lcon lc, l, mid
#define rcon rc, mid + 1, r
#define Mid int mid = l + r >> 1
int query(int k, int l, int r, dl x) {
if(l == r) return mx[k] > x;
if(x >= mx[k]) return 0;
Mid; if(mx[lc] <= x) return query(rcon, x);
return ans[k] - ans[lc] + query(lcon, x);
}
void update(int k, int l, int r, int x, dl v) {
if(l == r) return (void)(mx[k] = v, ans[k] = 1);
Mid; if(x <= mid) update(lcon, x, v);
else update(rcon, x, v);
mx[k] = max(mx[lc], mx[rc]);
ans[k] = ans[lc] + query(rcon, mx[lc]);
}
int main() {
scanf("%d %d", &n, &m);
for(int i = 1; i <= m; ++i) {
int l, x; scanf("%d %d", &l, &x);
update(1, 1, n, l, (dl) x / l * 1.0);
printf("%d\n", ans[1]);
}
return 0;
}

浙公网安备 33010602011771号