受不了自己如此脑残了。
卡了一个小时后发现是道水题。。。。。。
一开始分类讨论5种情况,没lazy_tag的都被我写上了。
结果无限RE。
各种静态查错。
然后果断想了个lazy-tag的方法。
结果发现其实是没忽略(a,a]这种情况,真是醉了。
然后发现又错了。。。。。。果然还是太弱了。
重新思考了下换了一种方法。
虽然说还是感觉很慢,不过还是交上去了,1000多MS,果然很慢。
先把点修改一下,(a代表[a+0.5,a)代表a-0.5],然后乘个2,就好做了。
其实一共就两种操作,区间修改,区间元素^=1(我管这个叫翻转),修改有两种,改成1和改成0。然后就好说了,随便搞搞。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; struct Node{ int l,r,set,rev; }tr[700000]; void pushup(int o){ if(tr[o<<1].set==tr[o<<1|1].set)tr[o].set=tr[o<<1].set; else tr[o].set=-1; } void pushdown(int o){ if(tr[o].rev){ tr[o<<1].rev^=1;tr[o<<1|1].rev^=1; if(tr[o<<1].set!=-1)tr[o<<1].set^=1; if(tr[o<<1|1].set!=-1)tr[o<<1|1].set^=1; tr[o].rev=0; } if(tr[o].set!=-1){ tr[o<<1].set=tr[o<<1|1].set=tr[o].set; tr[o<<1].rev=tr[o<<1|1].rev=0; } } void update(int o,int a,int b,int tp){ int l=tr[o].l,r=tr[o].r; if(l==a&&b==r){ if(tp==1){ //覆盖 tr[o].set=1;tr[o].rev=0; } if(tp==2){ //删除 tr[o].set=0;tr[o].rev=0; } if(tp==3){ //翻转 tr[o].rev^=1; if(tr[o].set!=-1) tr[o].set^=1; } }else{ pushdown(o); int m=l+r>>1; if(b<=m)update(o<<1,a,b,tp); else if(m<a)update(o<<1|1,a,b,tp); else{update(o<<1,a,m,tp);update(o<<1|1,m+1,b,tp);} pushup(o); } } void build(int o,int l,int r){ tr[o].l=l;tr[o].r=r; if(l==r)tr[o].set=0; else{ int m=l+r>>1; build(o<<1,l,m);build(o<<1|1,m+1,r); pushup(o); } } bool set[70000*2]; void calc(int o,int a,int b){ int l=tr[o].l,r=tr[o].r; if(l==a&&b==r){ if(a==b){ set[a]=tr[o].set; }else{ pushdown(o); int m=l+r>>1; calc(o<<1,a,m);calc(o<<1|1,m+1,b); } }else{ pushdown(o); int m=l+r>>1; if(b<=m)calc(o<<1,a,b); else if(m<a)calc(o<<1|1,a,b); else {calc(o<<1,a,m);calc(o<<1|1,m+1,b);} } } void print(){ calc(1,0,66000*2); bool flag=false; for(int i=0;i<140000-10;i++){ if(!set[i])continue; flag=true; if(i&1)printf("(%d,",(i-1)/2); else printf("[%d,",i/2); while(set[i+1])i++; if(i&1)printf("%d)",(i+1)/2); else printf("%d]",i/2); printf(" "); } if(!flag)printf("empty set"); } int main(){ build(1,0,70000*2); char opt[5],l,r;int a,b; while(scanf("%s",opt)==1){ l=getchar(); while(l!='('&&l!='[')l=getchar();scanf("%d",&a); r=getchar();scanf("%d",&b); while(r!=')'&&r!=']')r=getchar(); if(a==b&&(l=='('||r==')'))continue; if(l=='(')a=2*a+1; else a*=2; if(r==')')b=2*b-1; else b*=2; switch(opt[0]){ case 'U':update(1,a,b,1);break; case 'I':if(a>0)update(1,0,a-1,2);update(1,b+1,66000*2,2);break; case 'D':update(1,a,b,2);break; case 'C':if(a>0)update(1,0,a-1,2);update(1,b+1,66000*2,2);update(1,a,b,3);break; case 'S':update(1,a,b,3);break; } } print(); return 0; }