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;
}
posted @ 2023-10-31 16:46  Saka_Noa  阅读(9)  评论(0)    收藏  举报  来源