洛谷 P4198 楼房重建
一道线段树维护区间前缀最大值个数的好题。
思路
易得连接 的线段斜率为 。则题要求的就是满足 的 的个数。考虑线段树维护。
线段树上每个结点维护当前区间 的斜率 和只考虑 的前缀最大值个数 ,即不考虑 对 的影响。 pushup
是很容易的,对左、右儿子取 即可。考虑 怎么 pushup
。
引入一个新函数 calc(rt, l, r, x)
,它返回区间 内,假设 的前缀最大值为 , 内的 。
- 当 为叶子结点,若 返回 ,否则返回 。显然。
- 当 为非叶子结点,考虑左右子树两部分贡献分别计算。若 ,则左子树的贡献为
calc(ls, l, mid, x)
,右子树的贡献为 。因为在右子树中相当于前缀 为左子树的 ,因此 的贡献直接相减即可得到。若 ,则左子树的贡献为 ,右子树的贡献为calc(rs, mid + 1, r, x)
。
现在可以回头解决 pushup
的问题了:。左子树的 可以直接继承,因为左子树的区间为当前子树的区间的前缀;右子树的 就利用 计算。由于是只考虑 区间的,所以 设为 就行。
时间复杂度 。
代码
code
/* p_b_p_b txdy AThousandMoon txdy AThousandSuns txdy hxy txdy */ #include <bits/stdc++.h> #define pb push_back #define fst first #define scd second using namespace std; typedef long long ll; typedef long double ldb; typedef pair<ll, ll> pii; const int maxn = 100100; ll n, m, a[maxn]; struct treenode { ldb mx; int cnt; } tree[maxn << 2]; int calc(int rt, int l, int r, ldb x) { if (l == r) { return (x < (ldb)a[l] / l ? 1 : 0); } int mid = (l + r) >> 1; if (x < tree[rt << 1].mx) { return calc(rt << 1, l, mid, x) + tree[rt].cnt - tree[rt << 1].cnt; } else { return calc(rt << 1 | 1, mid + 1, r, x); } } void pushup(int x, int l, int r) { int mid = (l + r) >> 1; tree[x].mx = max(tree[x << 1].mx, tree[x << 1 | 1].mx); tree[x].cnt = tree[x << 1].cnt + calc(x << 1 | 1, mid + 1, r, tree[x << 1].mx); } void update(int rt, int l, int r, int x) { if (l == r) { tree[rt].mx = (ldb)a[l] / l; tree[rt].cnt = 1; return; } int mid = (l + r) >> 1; if (x <= mid) { update(rt << 1, l, mid, x); } else { update(rt << 1 | 1, mid + 1, r, x); } pushup(rt, l, r); } void solve() { scanf("%lld%lld", &n, &m); while (m--) { ll x, y; scanf("%lld%lld", &x, &y); a[x] = y; update(1, 1, n, x); printf("%d\n", tree[1].cnt); } } int main() { int T = 1; // scanf("%d", &T); while (T--) { solve(); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现