【模板】【动态开点线段树】【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;
}
posted @   glq_C  阅读(118)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示