//因为n很大,直接建树肯定会超时,所以要先离散化。节点设置一个lhas代表这个节点代表的区间左端点的位置,
1代表原位置,0代表被压下去了,设置一个rhas同理;然后如果根节点左孩子的rhas和右孩子的lhas都为1,则根
节点的sum为左右孩子sum之和减1,否则为左右孩子之和。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 80010
using namespace std;
int n,m;
int op[N],l[N],r[N];int ind[N],ind2[N];
struct point
{
int l,r,sum,cover;bool lhas,rhas;
}p[N*4];
void build(int o,int l,int r)
{
p[o].l=l;
p[o].r=r;
p[o].sum=1;
p[o].lhas=p[o].rhas=1;
p[o].cover=0;
if(l!=r)
{
int mid=(l+r)/2;
build(o*2,l,mid);
build(o*2+1,mid+1,r);
}
}
void update(int o,int l,int r,int add)
{
if(p[o].l==l&&p[o].r==r)
{
p[o].cover+=add;
if(l==r)
{
if(!p[o].cover)p[o].lhas=p[o].rhas=p[o].sum=1;
else p[o].lhas=p[o].rhas=p[o].sum=0;
}
else
{
if(!p[o].cover)
{
p[o].lhas=p[o*2].lhas,p[o].rhas=p[o*2+1].rhas;
p[o].sum=p[o*2].sum+p[o*2+1].sum;
if(p[o*2].rhas==1&&p[o*2+1].lhas==1)p[o].sum=p[o].sum-1;
}
else p[o].lhas=p[o].rhas=p[o].sum=0;
}
return;
}
int mid=(p[o].l+p[o].r)/2;
if(l>mid)update(o*2+1,l,r,add);
else if(r<=mid)update(o*2,l,r,add);
else
{
update(o*2,l,mid,add);
update(o*2+1,mid+1,r,add);
}
if(p[o].cover>0)return;
p[o].lhas=p[o*2].lhas,p[o].rhas=p[o*2+1].rhas;
p[o].sum=p[o*2].sum+p[o*2+1].sum;
if(p[o*2].rhas==1&&p[o*2+1].lhas==1)p[o].sum=p[o].sum-1;
}
int find(int x,int l,int r)
{
while(l<=r)
{
int mid=(l+r)/2;
if(ind2[mid]==x)return mid;
else if(ind2[mid]>x)r=mid-1;
else l=mid+1;
}
return -1;
}
int main()
{
//freopen("1.in","r",stdin);
int T;
cin>>T;
int k=1;
while(T--)
{
scanf("%d%d",&n,&m);
printf("Case #%d:\n",k++);
char C;
if(m>0)
{
for(int i=1;i<=m;i++)
{
getchar();
scanf("%c%d%d",&C,&l[i],&r[i]);
if(C=='p')op[i]=1;
else op[i]=-1;
ind[i]=l[i];
ind[i+m]=r[i];
}
sort(ind+1,ind+2*m+1);
int j=1;
for(int i=2;i<=2*m;i++)
{
if(ind[i]!=ind[i-1])ind[++j]=ind[i];
}
int ll=0,rr;
if(ind[1]==0)ll=1;
int cnt=1;
ind2[1]=ind[1];
for(int i=2;i<=j;i++)
{
if(ind[i]>ind[i-1]+1)ind2[++cnt]=ind[i-1]+1;
ind2[++cnt]=ind[i];
}
if(ind2[cnt]==n-1)rr=cnt;
else rr=cnt+1;
sort(ind2+1,ind2+1+cnt);
build(1,ll,rr);
for(int i=1;i<=m;i++)
{
int a=find(l[i],1,cnt),b=find(r[i],1,cnt);
update(1,a,b,op[i]);
printf("%d\n",p[1].sum);
}
}
}
return 0;
}
POJ3254--Corn Fields
最新推荐文章于 2018-10-15 10:18:28 发布