洛谷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;
}
浙公网安备 33010602011771号