题解:本题主要考查动态开点线段树
简要题意:给1-n的一段空区间,每次给出询问,z == 1 时将 x - y 区间填充,否则为空,问最后一共有多少空区间。
1.动态开点线段树:本题数据规模很多,单纯的线段树会MLE,这就需要动态开点。
代码如下:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int l,r,val;
}tree[15001000];//注意数组大小!
int p,size,n,q,l,r,m,lazy[15001000];
void pushdown(int p,int l,int r)
{
if(lazy[p]!=-1)
{
int mid=l+r>>1;
if(!tree[p].l)tree[p].l=++size;
if(!tree[p].r)tree[p].r=++size;
lazy[tree[p].l]=lazy[p];
lazy[tree[p].r]=lazy[p];
tree[tree[p].l].val=lazy[p]*(mid-l+1);
tree[tree[p].r].val=lazy[p]*(r-mid);
lazy[p]=-1;
}
}
void change(int&p,int x,int y,int l,int r,int k)
{
if(!p)p=++size;
if(x<=l&&r<=y){
tree[p].val=k*(r-l+1);
lazy[p]=k;
return;
}
pushdown(p,l,r);
int mid=(l+r)>>1;
if(x<=mid)change(tree[p].l,x,y,l,mid,k);
if(y>mid)change(tree[p].r,x,y,mid+1,r,k);
tree[p].val=tree[tree[p].l].val+tree[tree[p].r].val;
}
int main()
{
memset(lazy,-1,sizeof(lazy));
scanf("%d%d",&n,&q);
for(int i=1;i<=q;i++)
{
scanf("%d%d%d",&l,&r,&m);
if(m==1)change(p,l,r,1,n,1);
else change(p,l,r,1,n,0);
printf("%d\n",n-tree[p].val);
}
return 0;
}