Description
给你一个无限长的数组,初始的时候都为0,有3种操作:
操作1是把给定区间[l,r] 设为1,
操作2是把给定区间[l,r] 设为0,
操作3把给定区间[l,r] 0,1反转。
一共n个操作,每次操作后要输出最小位置的0。
Input
第一行一个整数n,表示有n个操作
接下来n行,每行3个整数op,l,r表示一个操作
Output
共n行,一行一个整数表示答案
Solution
考场上写挂了,没判端点重复。。。
其实不难,就一个离散化加线段树维护所有操作的l,r。
输入所有操作再离散化,用l,r建线段树即可。
注意一下将所有右端点r加1,找区间端点时直接用lower_bound查找第一个大于等于r+1的数的上一个数即可。
Code
#include<bits/stdc++.h>
#define inf 0x7fffffff
using namespace std;
int minn[800010][2];
int laz[800010];
bool lazr[800010];
void pushdown(int id,int l,int r){
int mid=(l+r)>>1;
if(laz[id]!=-1){
int x=laz[id];
minn[id*2][x]=l;
minn[id*2+1][x]=mid+1;
minn[id*2][x^1]=minn[id*2+1][x^1]=inf;
laz[id*2]=laz[id*2+1]=laz[id];
lazr[id*2]=lazr[id*2+1]=0;
laz[id]=-1;
}
if(lazr[id]){
lazr[id*2]^=1,lazr[id*2+1]^=1;
swap(minn[id*2][0],minn[id*2][1]);
swap(minn[id*2+1][0],minn[id*2+1][1]);
lazr[id]=0;
}
}
void build(int id,int l,int r){
laz[id]=-1;
minn[id][0]=l;
minn[id][1]=inf;
if(l==r) return;
int mid=(l+r)>>1;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
}
void update1(int id,int l,int r,int ul,int ur,int x){
if(ul<=l&&r<=ur){
minn[id][x]=l;
minn[id][x^1]=inf;
laz[id]=x;
lazr[id]=0;
return;
}
pushdown(id,l,r);
int mid=(l+r)>>1;
if(ul<=mid) update1(id*2,l,mid,ul,ur,x);
if(ur>mid) update1(id*2+1,mid+1,r,ul,ur,x);
minn[id][0]=min(minn[id*2][0],minn[id*2+1][0]);
minn[id][1]=min(minn[id*2][1],minn[id*2+1][1]);
}
void update2(int id,int l,int r,int ul,int ur){
if(ul<=l&&r<=ur){
swap(minn[id][0],minn[id][1]);
lazr[id]^=1;
return;
}
pushdown(id,l,r);
int mid=(l+r)>>1;
if(ul<=mid) update2(id*2,l,mid,ul,ur);
if(ur>mid) update2(id*2+1,mid+1,r,ul,ur);
minn[id][0]=min(minn[id*2][0],minn[id*2+1][0]);
minn[id][1]=min(minn[id*2][1],minn[id*2+1][1]);
}
struct data{
int op;
long long x,y;
}q[100010];
long long b[200020];
int n,tot=0;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
long long y,z;
scanf("%d%lld%lld",&x,&y,&z);
q[i]=(data){x,y,z};
tot++,b[tot]=y,tot++,b[tot]=z+1;
}
tot++,b[tot]=1;
sort(b+1,b+tot+1);
build(1,1,tot);
for(int i=1;i<=n;i++){
int l=lower_bound(b+1,b+tot+1,q[i].x)-b;
int r=lower_bound(b+1,b+tot+1,q[i].y+1)-b-1;
if(q[i].op==1) update1(1,1,tot,l,r,1);
if(q[i].op==2) update1(1,1,tot,l,r,0);
if(q[i].op==3) update2(1,1,tot,l,r);
printf("%lld\n",b[minn[1][0]]);
}
}