区间交并的题,感觉好纠结。
先递推覆盖标记 之后递推异或标记
再覆盖一段区间的时候,要把这个区间的异或标记全部清空
#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;
}