CF915E 题解(动态开点线段树)
题目传送门
简要题意:题面就挺简要的。
看到题目第一眼想到线段树,再看一眼数据范围,寄
,既然不能直接用线段树,那怎么办呢?可以离散化,为了避免麻烦的离散化,我们选择一种简单好用的方式, 动态开点线段树!!!!!
跟线段树差不多,只不过不再记录左右端点而是记录左右端点的编号,在需要创建这个儿子的时候再创建它,这样就能避免空间太大炸掉了,剩下的看代码理解吧。
code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long long ull;
const int N = 1.5e7 + 5, INF = 0x3f3f3f3f;
const ll mod = 1e9 + 7;
int n, q, rt;
struct segment_tree
{
int l, r, val, laz = -1;
}tr[N];
int idx;
void pushup(int x)
{
tr[x].val = tr[tr[x].l].val + tr[tr[x].r].val;
}
void pushdown(int x, int l, int r)
{
if(tr[x].laz == -1) return;
int mid = l + r >> 1;
if(!tr[x].l) tr[x].l = ++ idx;
tr[tr[x].l].val = tr[x].laz * (mid - l + 1);
tr[tr[x].l].laz = tr[x].laz;
if(!tr[x].r) tr[x].r = ++ idx;
tr[tr[x].r].val = tr[x].laz * (r - mid);
tr[tr[x].r].laz = tr[x].laz;
tr[x].laz = -1;
}
void update(int &x, int nl, int nr, int l, int r, int k)
{
if(!x) x = ++ idx;
if(nl <= l && r <= nr)
{
tr[x].val = (r - l + 1) * k;
tr[x].laz = k;
return;
}
pushdown(x, l, r);
int mid = l + r >> 1;
if(nl <= mid) update(tr[x].l, nl, nr, l, mid, k);
if(nr > mid) update(tr[x].r, nl, nr, mid + 1, r, k);
pushup(x);
}
int main() //主函数
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> q;
update(rt, 1, n, 1, n, 1);
while(q --)
{
int l, r, k;
cin >> l >> r >> k;
if(k == 1) update(rt, l, r, 1, n, 0);
else update(rt, l, r, 1, n, 1);
cout << tr[1].val << '\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框架的用法!