题目链接:https://vjudge.net/problem/POJ-3225
解题思路:这道题要是不看题解以本渣新现在的实力确实是做不出来。
以区间为基础建立线段树。
当X=‘U', 将区间T内的线段上的数字都置为1;当X='I', 将区间T外面的数字置为0;当X=‘D‘,将区间T内的数字置为0;当X=‘C',将区间T外的数字置为0,区间T内的数字0/1倒置;当X=‘S',将区间T内的数字0/1倒置。这就是整道题的精髓所在。
在AC代码中,lazy标记的使用值得细细品味,对于0/1倒置这种操作,如果对同一区间使用偶数次,那么就相当于没有操作,于是用lazy先给有这种操作的区间做好标记,用PushDown()函数保证在每次线段树更新到这个区间之前,0/1倒置的操作已经完成,lazy标志清0。PushDown()也算是一个重点吧,因为这个而WA了好几发。本来还有一个PushUp()函数的,但是对于这种类型的线段树,PushUp()其实有点行不通。
AC代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn=131072; 6 const int inf=131072; 7 int tree[maxn<<2]; 8 int lazy[maxn<<2]; 9 int ans[maxn+1]; 10 void PushDown(int rt){ 11 if(tree[rt]!=-1){ 12 tree[rt<<1|1]=tree[rt<<1]=tree[rt]; 13 lazy[rt<<1|1]=lazy[rt<<1]=0; 14 } 15 if(lazy[rt]){ 16 if(tree[rt<<1]!=-1) 17 tree[rt<<1]^=1; 18 else 19 lazy[rt<<1]^=1; 20 if(tree[rt<<1|1]!=-1) 21 tree[rt<<1|1]^=1; 22 else 23 lazy[rt<<1|1]^=1; 24 lazy[rt]=0; 25 } 26 tree[rt]=-1; 27 } 28 void change(int L,int R,int l,int r,int rt){ 29 if(L<=l&&r<=R){ 30 if(tree[rt]!=-1) 31 tree[rt]^=1; 32 else 33 lazy[rt]^=1; 34 return; 35 } 36 if(l==r) 37 return; 38 PushDown(rt); 39 int m=(l+r)>>1; 40 if(L<=m) change(L,R,l,m,rt<<1); 41 if(R>m) change(L,R,m+1,r,rt<<1|1); 42 } 43 void update(int L,int R,int c,int l,int r,int rt){ 44 if(L<=l&&r<=R){ 45 tree[rt]=c; 46 lazy[rt]=0; 47 return; 48 } 49 if(l==r) 50 return; 51 PushDown(rt); 52 int m=(l+r)>>1; 53 if(L<=m) update(L,R,c,l,m,rt<<1); 54 if(R>m) update(L,R,c,m+1,r,rt<<1|1); 55 } 56 void query(int l,int r,int rt){ 57 if(tree[rt]==1){ 58 if(lazy[rt]){ 59 tree[rt]=0; 60 lazy[rt]=0; 61 return; 62 } 63 for(int i=l;i<=r;i++){ 64 ans[i]=tree[rt]; 65 } 66 return; 67 } 68 if(tree[rt]==0) return; 69 if(l==r){ 70 return; 71 } 72 PushDown(rt); 73 int m=(l+r)>>1; 74 query(l,m,rt<<1); 75 query(m+1,r,rt<<1|1); 76 } 77 int main(){ 78 char in1[5],in2[20]; 79 while(scanf("%s %s",in1,in2)==2){ 80 int x,y; 81 sscanf(&in2[1],"%d",&x); 82 sscanf(strstr(in2,",")+1,"%d",&y); 83 x=x*2; y=y*2; 84 if(in2[0]=='(') x++; 85 if(strstr(in2,")")!=NULL) y--; 86 87 if(x>y){ 88 if(in1[0]=='I'||in1[0]=='C'){ 89 lazy[1]=tree[1]=0; 90 } 91 } 92 else{ 93 if(in1[0]=='U') update(x,y,1,0,inf,1); 94 else if(in1[0]=='I'){ 95 update(0,x-1,0,0,inf,1); 96 update(y+1,inf,0,0,inf,1); 97 } 98 else if(in1[0]=='D') 99 update(x,y,0,0,inf,1); 100 else if(in1[0]=='C'){ 101 change(x,y,0,inf,1); 102 update(0,x-1,0,0,inf,1); 103 update(y+1,inf,0,0,inf,1); 104 } 105 else 106 change(x,y,0,inf,1); 107 } 108 } 109 query(0,inf,1); 110 int flag=0; 111 int ind=0; 112 for(int i=0;i<=inf;i++){ 113 if(!flag&&ans[i]){ 114 if(ind) 115 printf(" "); 116 if(i%2) 117 printf("("); 118 else 119 printf("["); 120 printf("%d,",i/2); 121 ind++; 122 flag=1; 123 } 124 else if(flag&&!ans[i]){ 125 printf("%d",i/2); 126 if((i-1)%2) 127 printf(")"); 128 else 129 printf("]"); 130 flag=0; 131 } 132 } 133 if(!ind) printf("empty set"); 134 printf(" "); 135 return 0; 136 }