区间交并的题,感觉好纠结。
先递推覆盖标记 之后递推异或标记
再覆盖一段区间的时候,要把这个区间的异或标记全部清空
#include<map> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define lson (pos<<1) #define rson (pos<<1|1) const int maxn = 145555; const int maxd = 145550; char op[10],cmp[105]; int a,b; int c1[maxn << 2],c2[maxn << 2]; bool vis[maxn] = {0}; void change(int pos){ if(c1[pos] != -1) c1[pos] ^= 1; else c2[pos] ^= 1; } void pushdown(int pos){ if(c1[pos] != -1){ c1[lson] = c1[rson] = c1[pos]; c2[lson] = c2[rson] = 0; c1[pos] = -1; } if(c2[pos]){ change(lson); change(rson); c2[pos] = 0; } } void update(char op,int L,int R,int l,int r,int pos){ if(l <= L && R <= r){ if(op == 'U'){ c1[pos] = 1; //改变覆盖标记 c2[pos] = 0; } if(op == 'D'){ c1[pos] = 0; //改变覆盖标记 c2[pos] = 0; } if(op == 'C' || op == 'S'){ change(pos); } return; } pushdown(pos); int mid = (L + R) >> 1; if(l <= mid) update(op,L,mid,l,r,lson); else if(op == 'I' || op == 'C'){ c2[lson] = c1[lson] = 0; } if(mid < r) update(op,mid + 1,R,l,r,rson); else if(op == 'I' || op == 'C'){ c2[rson] = c1[rson] = 0; } } void query(int l,int r,int pos){ if(c1[pos] == 1){ for(int i = l; i <= r; i++) vis[i] = true; return; } else if(c1[pos] == 0) return; if(l == r) return; pushdown(pos); int mid = (l + r) >> 1; query(l,mid,lson); query(mid + 1,r,rson); } int main(){ c1[1] = c2[1] = 0; while(scanf("%s",&op) != EOF){ scanf("%s",cmp); int L = strlen(cmp),pos; sscanf(cmp + 1,"%d",&a); pos = strchr(cmp,',') - cmp; sscanf(cmp + pos + 1,"%d",&b); a <<= 1; b <<= 1; if(cmp[0] == '(') a ++; if(cmp[L - 1] == ')') b --; if(a > b){ if(op[0] == 'C' || op[0] == 'I'){ c1[1] = c2[1] = 0; } } else{ update(op[0],0,maxd,a,b,1); } } query(0,maxd,1); bool flag = false; int i; for(i = 0; i <= maxd;i++){ if(vis[i]){ if(flag) printf(" "); if(i & 1) printf("(%d,",(i - 1) / 2); else printf("[%d,", i / 2); for(i = i + 1; vis[i]; i++); i --; if(i & 1) printf("%d)",(i + 1) / 2); else printf("%d]", i / 2); flag = true; } } if(!flag) printf("empty set"); return 0; }
原文:http://blog.csdn.net/u013451221/article/details/45272905