【模板】【动态开点线段树】【CF915E】
【模板】【动态开点线段树】【CF915E】
支持区间覆盖的动态开点线段树的模板
一开始在结构体记录区间的左右端点,但空间卡得太紧没过,去掉以后又改了一下结构体大小才过。
这是刚开始的代码
#include<bits/stdc++.h> using namespace std; inline int read() { register int x=0,w=1; register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if(ch=='-') {w=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*w; } const int N=1e7; int n,m; struct node{ int l,r,ls,rs,tag,sum; }t[N]; int rt,tot; int build(int l,int r) { tot++; t[tot].l=l,t[tot].r=r; return tot; } void pushup(int x) { t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum; } void pushdown(int x) { if(t[x].tag) { t[x].tag=0; int mid=t[x].l+t[x].r>>1; if(!t[x].ls) t[x].ls=build(t[x].l,mid); if(!t[x].rs) t[x].rs=build(mid+1,t[x].r); if(t[x].sum) { t[t[x].ls].sum=t[t[x].ls].r-t[t[x].ls].l+1; t[t[x].ls].tag=1; t[t[x].rs].sum=t[t[x].rs].r-t[t[x].rs].l+1; t[t[x].rs].tag=1; } else { t[t[x].ls].sum=0; t[t[x].ls].tag=1; t[t[x].rs].sum=0; t[t[x].rs].tag=1; } } } void change(int x,int l,int r,int c) { if(t[x].l>=l&&t[x].r<=r) { if(c) t[x].sum=t[x].r-t[x].l+1; else t[x].sum=0; t[x].tag=1; return; } int mid=t[x].l+t[x].r>>1; pushdown(x); if(l<=mid){ if(!t[x].ls) t[x].ls=build(t[x].l,mid); change(t[x].ls,l,r,c); } if(r>mid){ if(!t[x].rs) t[x].rs=build(mid+1,t[x].r); change(t[x].rs,l,r,c); } pushup(x); } int main() { n=read();m=read(); rt=build(1,n); for(int i=1;i<=m;++i) { int l=read(),r=read(),k=read(); change(1,l,r,k&1); printf("%d\n",n-t[1].sum); } return 0; }
改后的代码
#include<bits/stdc++.h> using namespace std; inline int read() { register int x=0,w=1; register char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar(); if(ch=='-') {w=-1;ch=getchar();} while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} return x*w; } const int N=1e7+5e6; int n,m; struct node{ int ls,rs,tag,sum; }t[N]; int rt,tot; int build() { tot++; return tot; } void pushup(int x) { t[x].sum=t[t[x].ls].sum+t[t[x].rs].sum; } void pushdown(int x,int l,int r) { if(t[x].tag) { t[x].tag=0; int mid=l+r>>1; if(!t[x].ls) t[x].ls=build(); if(!t[x].rs) t[x].rs=build(); if(t[x].sum) { t[t[x].ls].sum=mid-l+1; t[t[x].ls].tag=1; t[t[x].rs].sum=r-mid; t[t[x].rs].tag=1; } else { t[t[x].ls].sum=0; t[t[x].ls].tag=1; t[t[x].rs].sum=0; t[t[x].rs].tag=1; } } } void change(int x,int l,int r,int c,int L,int R) { if(L>=l&&R<=r) { if(c) t[x].sum=R-L+1; else t[x].sum=0; t[x].tag=1; return; } int mid=L+R>>1; pushdown(x,L,R); if(l<=mid){ if(!t[x].ls) t[x].ls=build(); change(t[x].ls,l,r,c,L,mid); } if(r>mid){ if(!t[x].rs) t[x].rs=build(); change(t[x].rs,l,r,c,mid+1,R); } pushup(x); } int main() { n=read();m=read(); rt=build(); for(int i=1;i<=m;++i) { int l=read(),r=read(),k=read(); change(1,l,r,k&1,1,n); printf("%d\n",n-t[1].sum); } return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现