把可能的答案都离散。
tg1 是区间推平标记, tg2 是区间取反标记。
评测记录:http://codeforces.com/contest/817/submission/102360584
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN=2e5+10;
struct T{int op,l,r;}a[MAXN];
struct Tree{int l,r,sum,tg1,tg2;}t[MAXN];
int n,tot,b[MAXN],ct,rt;
inline void pushup(int x){t[x].sum=t[t[x].l].sum+t[t[x].r].sum;}
int build(int l,int r){
int q=++tot;
t[q].tg1=-1;
if(l==r)return q;
int mid=(l+r)>>1;
t[q].l=build(l,mid);
t[q].r=build(mid+1,r);
return q;
}
inline void pushdown(int x,int l,int r){
int mid=(l+r)>>1;
if(t[x].tg1!=-1){
int p=t[x].tg1;
t[x].tg1=-1;
t[x].tg2=0;
if(p){
t[t[x].l].sum=mid-l+1;
t[t[x].r].sum=r-mid;
t[t[x].l].tg1=p;
t[t[x].r].tg1=p;
}
else{
t[t[x].l].sum=0;
t[t[x].r].sum=0;
t[t[x].l].tg1=p;
t[t[x].r].tg1=p;
}
return;
}
if(t[x].tg2){
int p=t[x].tg2;
t[x].tg2=0;
t[t[x].l].tg2^=1;
t[t[x].r].tg2^=1;
if(t[t[x].l].tg1!=-1) t[t[x].l].tg1^=1;
if(t[t[x].r].tg1!=-1) t[t[x].r].tg1^=1;
t[t[x].l].sum=(mid-l+1-t[t[x].l].sum);
t[t[x].r].sum=(r-mid-t[t[x].r].sum);
}
}
void change(int x,int l,int r,int ql,int qr,int v){
if(l>=ql&&r<=qr){
t[x].tg1=v;
if(t[x].tg2) t[x].tg2=0;
t[x].sum=v*(r-l+1);
return;
}
int mid=(l+r)>>1;
pushdown(x,l,r);
if(ql<=mid)change(t[x].l,l,mid,ql,qr,v);
if(mid<qr)change(t[x].r,mid+1,r,ql,qr,v);
pushup(x);
}
void xchange(int x,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr){
t[x].tg2=1;
if(t[x].tg1!=-1) t[x].tg1 ^= 1;
t[x].sum=r-l+1-t[x].sum;
return;
}
int mid=(l+r)>>1;
pushdown(x,l,r);
if(ql<=mid)xchange(t[x].l,l,mid,ql,qr);
if(mid<qr)xchange(t[x].r,mid+1,r,ql,qr);
pushup(x);
}
int query(int x,int l,int r){
pushdown(x,l,r);
int mid=l+r>>1;
if(l==r) return b[l];
if(t[t[x].l].sum==mid-l+1)return query(t[x].r,mid+1,r);
return query(t[x].l,l,mid);
pushup(x);
}
signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;++i){
scanf("%lld%lld%lld",&a[i].op,&a[i].l,&a[i].r);
b[++ct]=a[i].l;
b[++ct]=a[i].r;
b[++ct]=a[i].r+1;
b[++ct]=a[i].l+1;
if(a[i].l>1)b[++ct]=a[i].l-1;
if(a[i].r>1)b[++ct]=a[i].r-1;
}
b[++ct]=1;
sort(b+1,b+ct+1);
int L=unique(b+1,b+ct+1)-b-1;
rt=build(1,L);
for(int i=1;i<=n;++i){
a[i].l=lower_bound(b+1,b+L+1,a[i].l)-b;
a[i].r=lower_bound(b+1,b+L+1,a[i].r)-b;
if(a[i].op!=3){change(rt,1,L,a[i].l,a[i].r,a[i].op==1?1:0);}
else{xchange(rt,1,L,a[i].l,a[i].r);}
if(t[1].sum==L)printf("%d\n",b[L]+1);
else printf("%lld\n",query(rt,1,L));
}
return 0;
}