点此看题
本题最关键的地方在于离散化,因为原来的数据范围达到了 1 e 18 1e18 1e18,但如果离散到 n n n的 1 e 5 1e5 1e5级别的话就比较好做了。但是只离散 l , r l,r l,r是不够的,把 l + 1 , l − 1 , r + 1 , r − 1 l+1,l-1,r+1,r-1 l+1,l−1,r+1,r−1都离散一下是肯定不会错的(代码中只离散了 r + 1 r+1 r+1,这一部分不要参考),注意还要离散 1 1 1。
离散化之后搞一个权值线段树维护 3 3 3种操作,搞一个覆盖标记和翻转标记,翻转的时候看有没有覆盖标记,没有的话才搞翻转标记。
#include
#include
using namespace std;
#define int long long
const int M = 100005;
int read()
{
int x=0,f=1;char c;
while((c=getchar())<'0' || c>'9') {if(c=='-') f=-1;}
while(c>='0' && c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
int n,m,op[M],l[M],r[M],q[3*M];
int sum[12*M],tag[12*M],rev[12*M];
void build(int i,int l,int r)
{
sum[i]=rev[i]=0;tag[i]=-1;
if(l==r) return ;
int mid=(l+r)>>1;
build(i<<1,l,mid);
build(i<<1|1,mid+1,r);
}
void up(int i)
{
sum[i]=sum[i<<1]+sum[i<<1|1];
}
void down(int i,int l,int r)
{
int mid=(l+r)>>1;
if(tag[i]!=-1)
{
tag[i<<1]=tag[i];
tag[i<<1|1]=tag[i];
rev[i<<1]=0;rev[i<<1|1]=0;
if(tag[i]==0)
sum[i<<1]=sum[i<<1|1]=0;
else
{
sum[i<<1]=mid-l+1;//nmsl cnm nmb wrnm
sum[i<<1|1]=r-mid;
}
tag[i]=-1;
}
if(rev[i])
{
if(tag[i<<1]!=-1) tag[i<<1]^=1;
else rev[i<<1]^=1;
if(tag[i<<1|1]!=-1) tag[i<<1|1]^=1;
else rev[i<<1|1]^=1;
sum[i<<1]=mid-l+1-sum[i<<1];
sum[i<<1|1]=r-mid-sum[i<<1|1];
rev[i]=0;
}
}
void upd(int i,int l,int r,int L,int R,int t)
{
if(l>R || L>r) return ;
if(L<=l && r<=R)
{
if(t==1)
{
tag[i]=1;
rev[i]=0;
sum[i]=r-l+1;
}
if(t==2)
{
tag[i]=0;
rev[i]=0;
sum[i]=0;
}
if(t==3)
{
if(tag[i]!=-1) tag[i]^=1;
else rev[i]^=1;
sum[i]=r-l+1-sum[i];
}
return ;
}
int mid=(l+r)>>1;
down(i,l,r);
upd(i<<1,l,mid,L,R,t);
upd(i<<1|1,mid+1,r,L,R,t);
up(i);
}
int ask(int i,int l,int r)
{
if(l==r) return l;
down(i,l,r);
int mid=(l+r)>>1;
if(sum[i<<1]<mid-l+1) return ask(i<<1,l,mid);
return ask(i<<1|1,mid+1,r);
}
signed main()
{
n=read();
q[++m]=1;
for(int i=1;i<=n;i++)
{
op[i]=read(),l[i]=read(),r[i]=read();
q[++m]=l[i];q[++m]=r[i];q[++m]=r[i]+1;
}
sort(q+1,q+1+m);
m=unique(q+1,q+1+m)-q-1;
build(1,1,m);
for(int i=1;i<=n;i++)
{
l[i]=lower_bound(q+1,q+1+m,l[i])-q;
r[i]=lower_bound(q+1,q+1+m,r[i])-q;
upd(1,1,m,l[i],r[i],op[i]);
printf("%lld\n",q[ask(1,1,m)]);
}
}