线段树 求 区间 交,并,补。。
区间并:[L,R] 赋值为 1 即可
区间交:[0,L) (R,MAXN]更新为 0
区间 S-T: [L,R] 更新为 0
区间 T-S:[0,L) (R,MAXN] 更新为 0,[L,R] 1 更新为 0,0更新为 1,即进行异或操作
区间对称差:[L,R] 1 更新为 0,0更新为 1. ( 对称差也可以定义为 (S并T)-(S交T) )
接下来要处理 开区间和闭区间问题
可以这么做,将区间扩大两倍,即端点值 x2,对于 左 端点 偶数表示 闭区间 ,碰到 开区间就将 + 1 变成奇数
对于 右端点 ,偶数表示 闭区间, 碰到 开区间 就 - 1 变成奇数
#include<iostream>
using namespace std;
#define lson u<<1
#define rson u<<1|1
#define MAXN 131100
bool visited[MAXN]={0};
struct Node{
int lef,rig,XOR,COVER;//异或标记,覆盖标记
}T[MAXN<<2];
void Build(int u,int l,int r){
T[u].lef=l;T[u].rig=r;
T[u].COVER=T[u].XOR=0;
if(l==r)return;
int mid=(l+r)>>1;
Build(lson,l,mid);Build(rson,mid+1,r);
}
void MakeXOR(int u){//进行异或时判断,如果有cover则转换状态,否则异或操作改变状态
if(T[u].COVER!=-1)T[u].COVER^=1;
else T[u].XOR^=1;
}
void PushDown(int u){
if(T[u].COVER!=-1){
T[lson].COVER=T[rson].COVER=T[u].COVER;
T[lson].XOR=T[rson].XOR=0;//有cover时异或操作失效
T[u].COVER=-1;
}
if(T[u].XOR){
MakeXOR(lson);MakeXOR(rson);
T[u].XOR=0;
}
}
void Update(int u,int l,int r,char cmd){
if(l<=T[u].lef&&T[u].rig<=r){
if(cmd=='U'){T[u].COVER=1;T[u].XOR=0;}
else if(cmd=='D'){T[u].COVER=T[u].XOR=0;}
else if(cmd=='C'||cmd=='S')MakeXOR(u);
}
else {
PushDown(u);
if(l<=T[lson].rig)Update(lson,l,r,cmd);
else if(cmd=='I'||cmd=='C')T[lson].COVER=T[lson].XOR=0;//左子树为空集
if(r>=T[rson].lef)Update(rson,l,r,cmd);
else if(cmd=='I'||cmd=='C')T[rson].COVER=T[rson].XOR=0;//右子树为空集
}
}
void Query(int u){
if(T[u].COVER==1){
for(int i=T[u].lef;i<=T[u].rig;i++)visited[i]=true;return;
}
if(T[u].COVER==0||T[u].lef==T[u].rig)return;
PushDown(u);
Query(lson);Query(rson);
}
void GetAns(){
bool flag=false;
int ll=-1,rr=0;
for(int i=0;i<=MAXN;i++){
if(visited[i]==true){
if(ll==-1)ll=i;
rr=i;
}
else if(ll!=-1){
if(flag)putchar(' ');flag=true;
printf("%c%d,%d%c",ll&1?'(':'[',ll>>1,(rr+1)>>1,rr&1?')':']');
ll=-1;
}
}
if(!flag)printf("empty set");puts("");
}
int main(){
char cmd;
char bkl,bkr;//左括号,右括号
int st,ed;//区间左端点,右端点
Build(1,0,MAXN);//从0开始,因为区间端点可能为0
while(scanf(" %c",&cmd)==1){
scanf(" %c%d,%d%c",&bkl,&st,&ed,&bkr);
st=(bkl=='('?(st<<1|1):st<<1);
ed=(bkr==')'?(ed<<1)-1:ed<<1);
if(st>ed){if(cmd=='I'||cmd=='C')T[1].COVER=T[1].XOR=0;}//空集
else Update(1,st,ed,cmd);
}
Query(1);GetAns();
return 0;
}