题意:给你n个区间,1操作表示把[l,r]赋值为1,2操作表示把[l,r]赋值为0,3操作表示把[l,r]异或1;
求第一个不为0的正整数。
思路:对于所有区间[l,r]取出l,r,r+1三个点;
离散化放入线段树中去
现在需要区间修改,区间异或,查询
需要两个lazy标记,一个存修改的值,一个存是否异或1.
区间查询log查找即可,详见代码。
小trick:需要加入最小值,即是1的情况;
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> #include<bitset> #include<time.h> using namespace std; #define LL long long #define pi (4*atan(1.0)) #define eps 1e-4 #define bug(x) cout<<"bug"<<x<<endl; const int N=3e5+10,M=4e6+10,inf=2147483647,mod=1e9+7; const LL INF=1e18+10,MOD=1e9+7; int L=3e5+10; struct LT { int sum[N<<2],to[N<<2],sw[N<<2]; void pushdown(int pos,int l,int r) { int mid=(l+r)>>1; if(to[pos]!=-1) { to[pos<<1]=to[pos]; to[pos<<1|1]=to[pos]; sum[pos<<1]=to[pos]*(mid-l+1); sum[pos<<1|1]=to[pos]*(r-mid); to[pos]=-1; sw[pos]=0; } if(sw[pos]) { if(to[pos<<1]!=-1)to[pos<<1]=!to[pos<<1]; else sw[pos<<1]=!sw[pos<<1]; if(to[pos<<1|1]!=-1)to[pos<<1|1]=!to[pos<<1|1]; else sw[pos<<1|1]=!sw[pos<<1|1]; sum[pos<<1]=(mid-l+1)-sum[pos<<1]; sum[pos<<1|1]=(r-mid)-sum[pos<<1|1]; sw[pos]=0; } } void build(int l,int r,int pos) { to[pos]=-1; sw[pos]=0; sum[pos]=0; if(l==r)return; int mid=(l+r)>>1; build(l,mid,pos<<1); build(mid+1,r,pos<<1|1); } void update(int L,int R,int c,int l,int r,int pos) { if(L<=l&&r<=R) { if(c==2) { if(to[pos]!=-1)to[pos]=!to[pos]; else sw[pos]=!sw[pos]; } else { to[pos]=c; sw[pos]=0; } if(c==2)sum[pos]=r-l+1-sum[pos]; else sum[pos]=(r-l+1)*c; return; } pushdown(pos,l,r); int mid=(l+r)>>1; if(L<=mid)update(L,R,c,l,mid,pos<<1); if(R>mid) update(L,R,c,mid+1,r,pos<<1|1); sum[pos]=sum[pos<<1|1]+sum[pos<<1]; } int query(int l,int r,int pos) { //cout<<l<<" "<<r<<" "<<sum[pos]<<" "<<to[pos]<<endl; if(l==r)return l; pushdown(pos,l,r); //cout<<sum[pos<<1]<<" "<<sum[pos<<1|1]<<endl; int mid=(l+r)>>1; if(sum[pos<<1]==mid-l+1)return query(mid+1,r,pos<<1|1); else return query(l,mid,pos<<1); } }tree; int t[N],len; LL l[N],r[N],s[N]; int getpos(LL x) { int pos=lower_bound(s+1,s+len,x)-s; return pos; } int main() { int n,k=0; scanf("%d",&n); s[++k]=1; for(int i=1;i<=n;i++) scanf("%d%lld%lld",&t[i],&l[i],&r[i]),s[++k]=l[i],s[++k]=r[i],s[++k]=r[i]+1; sort(s+1,s+1+k); len=unique(s+1,s+1+k)-s; tree.build(1,L,1); for(int i=1;i<=n;i++) { int z=getpos(l[i]),y=getpos(r[i]); if(t[i]==1)tree.update(z,y,1,1,L,1); else if(t[i]==2)tree.update(z,y,0,1,L,1); else if(t[i]==3)tree.update(z,y,2,1,L,1); int x=tree.query(1,L,1); //cout<<"xxx "<<x<<" "<<tree.sum[1]<<endl; printf("%lld ",s[x]); } return 0; }