洛谷P4198 楼房重建 题解 线段树单侧递归

题目链接:https://www.luogu.com.cn/problem/P4198

解题思路:完全来自 ikusiad大佬的博客

示例程序:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;

int n, m;

double tmax[maxn<<2]; // 最大斜率
int tcnt[maxn<<2];  // 最大前缀(前面的斜率都 < 它的斜率)个数
#define lson l, mid, u<<1
#define rson mid+1, r, u<<1|1

// 查询斜率 > h 的个数
int query(double h, int l, int r, int u) {
    if (l == r) {
        return tmax[u] > h;
    }
    int mid = l + r >> 1;
    if (tmax[u<<1] <= h) {
        return query(h, rson);
    }
    else {
        return tcnt[u] - tcnt[u<<1] + query(h, lson);
    }
}

void push_up(int l, int r, int u) {
    int mid = l + r >> 1;
    tmax[u] = max(tmax[u<<1], tmax[u<<1|1]);
    tcnt[u] = tcnt[u<<1] + query(tmax[u<<1], rson);
}

void update(int p, double h, int l, int r, int u) {
    if (l == r) {
        tcnt[u] = 1;
        tmax[u] = h;
        return;
    }
    int mid = l + r >> 1;
    (p <= mid) ? update(p, h, lson) : update(p, h, rson);
    push_up(l, r, u);
}

int main() {
    scanf("%d%d", &n, &m);
    while (m--) {
        int x, y;
        scanf("%d%d", &x, &y);
        update(x, 1.0 * y / x, 1, n, 1);
        printf("%d\n", tcnt[1]);
    }
    return 0;
}
posted @ 2026-04-15 15:34  quanjun  阅读(3)  评论(0)    收藏  举报