楼房重建线段树
维护前缀最大值个数。
对 pushup
操作进行修改。
定义 solve(x, lim)
为前面这个区间的最大值为 lim
,
如果
考虑
如果左儿子最大值小于
总复杂度
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5 + 5, INF = 0x3f3f3f3f;
const LL mod = 998244353;
int n, m;
struct Segment_Tree {
struct Node {
int l, r, val;
double maxv;
#define l(x) tr[x].l
#define r(x) tr[x].r
#define val(x) tr[x].val
#define mx(x) tr[x].maxv
} tr[N << 2];
void build(int l, int r, int x) {
tr[x] = {l, r};
if (l == r) return;
int mid = (l + r) / 2;
build(l, mid, x * 2), build(mid + 1, r, x * 2 + 1);
}
int solve(int x, double lim) {
if (mx(x) <= lim) return 0;
if (l(x) == r(x)) return 1;
if (mx(x * 2) <= lim) return solve(x * 2 + 1, lim);
else return solve(x * 2, lim) + val(x) - val(x * 2);
}
void pushup(int x) {
mx(x) = max(mx(x * 2), mx(x * 2 + 1));
val(x) = val(x * 2) + solve(x * 2 + 1, mx(x * 2));
}
void update(int p, int x, double v) {
if (l(x) == r(x)) {
mx(x) = v;
val(x) = 1;
return;
}
int mid = (l(x) + r(x)) / 2;
if (p <= mid) update(p, x * 2, v);
else update(p, x * 2 + 1, v);
pushup(x);
}
} SegT;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
cin >> n >> m;
SegT.build(1, n, 1);
for (int i = 1; i <= m; i ++) {
int x, y;
cin >> x >> y;
SegT.update(x, 1, (double)y / x);
cout << SegT.val(1) << '\n';
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!