线段树维护区间取反和区间覆盖操作。
注意他们的优先级。

#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef pair<int,pll> plll; const int N=1e6+10; struct node{ int l,r; int rev; int cnt; int lazy; }tr[N]; int ans[N]; void build(int u,int l,int r){ if(l==r){ tr[u]={l,r,0,0,-1}; } else{ tr[u]={l,r,0,0,-1}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); } } void pushdown(int u){ if(tr[u].lazy!=-1){ int x=tr[u].lazy; tr[u<<1].lazy=x; tr[u<<1|1].lazy=x; tr[u<<1].rev=0; tr[u<<1|1].rev=0; tr[u].lazy=-1; } if(tr[u].rev){ tr[u<<1].rev^=1; tr[u<<1|1].rev^=1; tr[u].rev=0; } } void modify(int u,int l,int r,int x){ if(tr[u].l>=l&&tr[u].r<=r){ tr[u].lazy=x; tr[u].rev=0; return ; } pushdown(u); int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,r,x); if(r>mid) modify(u<<1|1,l,r,x); } void change(int u,int l,int r){ if(tr[u].l>=l&&tr[u].r<=r){ tr[u].rev^=1; return ; } pushdown(u); int mid=tr[u].l+tr[u].r>>1; if(l<=mid) change(u<<1,l,r); if(r>mid) change(u<<1|1,l,r); } void query(int u,int l,int r){ if(l==r){ if(tr[u].lazy==-1){ if(tr[u].rev==0) ans[l]=0; else ans[l]=1; } else{ ans[l]=tr[u].lazy^tr[u].rev; } return ; } pushdown(u); int mid=l+r>>1; query(u<<1,l,mid); query(u<<1|1,mid+1,r); } int main(){ //ios::sync_with_stdio(false); int m; string s; build(1,0,150000); int n=150000; while(getline(cin,s)){ int L=0,R=0,i=3; while(s[i]>='0'&&s[i]<='9') L=L*10+s[i++]-'0'; L<<=1; L+=(s[2]=='('); i++; while(s[i]>='0'&&s[i]<='9') R=R*10+s[i++]-'0'; R<<=1; R-=(s[i]==')');//读入数据需要一点点改变,注意细节 if(s[0]=='U') modify(1,L,R,1);else if(s[0]=='I'){ if(0<=L-1) modify(1,0,L-1,0); if(R+1<=n) modify(1,R+1,n,0); }else if(s[0]=='D') modify(1,L,R,0);else if(s[0]=='C'){ if(0<=L-1) modify(1,0,L-1,0); if(R+1<=n) modify(1,R+1,n,0); change(1,L,R); }else if(s[0]=='S') change(1,L,R); } query(1,0,n); int cnt=0; int i; int L=0,R=0; for(int i=0;i<=n;i++){ if(ans[i]&&(i==0||!ans[i-1])) L=i; if(ans[i]&&(i==n||!ans[i+1])){ R=i; cnt++; if(L&1) printf("(%d,",L/2); else printf("[%d,",L/2); if(R&1) printf("%d) ",R/2+1); else printf("%d] ",R/2); } } if(!cnt) cout<<"empty set"<<endl; return 0; }