线段树 求 区间 交,并,补。。
区间并:[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; }