社区讨论
关于动态开点线段树的空间问题
学术版参与者 5已保存回复 17
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 17 条
- 当前快照
- 1 份
- 快照标识符
- @mhz4e0qr
- 此快照首次捕获于
- 2025/11/15 01:16 3 个月前
- 此快照最后确认于
- 2025/11/16 14:21 3 个月前
这是 CF915E 的代码
CPP#include<bits/stdc++.h>
using namespace std;
const int N=40*(3e5+10); int rt,tot;
struct Node {
int lc,rc,w,lzy;
void tag(int x,int len) { w=x*len,lzy=x+1; }
}t[N];
void pushup(int u) { t[u].w=t[t[u].lc].w+t[t[u].rc].w; }
void pushdown(int u,int l,int r) {
if(!t[u].lzy) return;
int m=(l+r)>>1;
if(!t[u].lc) t[u].lc=++tot;
t[t[u].lc].tag(t[u].lzy-1,m-l+1);
if(!t[u].rc) t[u].rc=++tot;
t[t[u].rc].tag(t[u].lzy-1,r-m);
t[u].lzy=0;
}
void update(int &u,int l,int r,int ul,int ur,int x) {
//cout<<u<<' '<<l<<' '<<r<<' '<<ul<<' '<<ur<<' '<<x<<'\n';
if(!u) u=++tot;
if(ul<=l&&r<=ur) {
t[u].tag(x,r-l+1);
return;
}
pushdown(u,l,r);
int m=(l+r)>>1;
if(ul<=m) update(t[u].lc,l,m,ul,ur,x);
if(ur>m) update(t[u].rc,m+1,r,ul,ur,x);
pushup(u);
}
/*int query(int &u,int l,int r,int ql,int qr) {
if(!u) u=++tot;
if(ql<=l&&r<=qr) return t[u].w;
pushdown(u,l,r);
int m=(l+r)>>1;
if(qr<=m) return query(t[u].lc,l,m,ql,qr);
if(ql>m) return query(t[u].rc,m+1,r,ql,qr);
return query(t[u].lc,l,m,ql,qr)+query(t[u].rc,m+1,r,ql,qr);
}*/
int main() {
ios::sync_with_stdio(false),cin.tie(nullptr);
int n,q; cin>>n>>q;
while(q--) {
int k,l,r; cin>>l>>r>>k;
if(k==1) update(rt,1,n,l,r,1);
else update(rt,1,n,l,r,0);
cout<<n-t[rt].w<<'\n';
//cout<<'\n';
//for(int i=1;i<=20;i++) cout<<i<<' '<<t[i].lc<<' '<<t[i].rc<<' '<<t[i].w<<' '<<t[i].lzy<<'\n';
}
return 0;
}
理论上动态开点线段树只要 的空间。
但第三行的空间定义必须要 才够,为什么?
究竟要开多大才行?
回复
共 17 条回复,欢迎继续交流。
正在加载回复...