萌新刚学线段树,求助线段树上找最左边的0
查看原帖
萌新刚学线段树,求助线段树上找最左边的0
128591
Refined_heart楼主2020/12/26 10:20

把可能的答案都离散。

tg1tg1 是区间推平标记, tg2tg2 是区间取反标记。

评测记录: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;
}
2020/12/26 10:20
加载中...