MnZn求调线段树
查看原帖
MnZn求调线段树
464001
5793__qwq楼主2023/7/17 21:43
#include<bits/stdc++.h>
#define N 100001<<2
using namespace std;
int n,m,f,x,y,a[N],s0[N],s1[N],l0[N],l1[N],r0[N],r1[N],bl0[N],bl1[N],re[N],eq0[N],eq1[N];
void print(int x,int l,int r){
	cout<<l<<" "<<r<<':'<<s0[x]<<" "<<s1[x]<<" "<<l0[x]<<" "<<l1[x]<<" "<<r0[x]<<" "<<r1[x]<<" "<<bl0[x]<<" "<<bl1[x]<<'\n';
	if(l==r)return;
	int m=l+r>>1;
	print(x<<1,l,m);
	print(x<<1|1,m+1,r);
}
void get(int x,int a,int b,int c,int d,int e,int f,int g,int h){s0[x]=a;s1[x]=b;l0[x]=c;l1[x]=d;r0[x]=e;r1[x]=f;bl0[x]=g;bl1[x]=h;}
void pushup(int x){
	s0[x]=s0[x<<1]+s0[x<<1|1];
	s1[x]=s1[x<<1]+s1[x<<1|1];
	if(l1[x<<1|1]==0)r0[x]=r0[x<<1|1]+r0[x<<1];else r0[x]=r0[x<<1|1];
	if(r1[x<<1|1]==0)l0[x]=l0[x<<1|1]+l0[x<<1];else l0[x]=l0[x<<1|1];
	if(l0[x<<1|1]==0)r1[x]=r1[x<<1|1]+r1[x<<1];else r1[x]=r1[x<<1|1];
	if(r0[x<<1|1]==0)l1[x]=l1[x<<1|1]+l1[x<<1];else l1[x]=l1[x<<1|1];
	bl0[x]=max(max(bl0[x<<1],bl0[x<<1|1]),r0[x<<1]+l0[x<<1|1]);
	bl1[x]=max(max(bl1[x<<1],bl1[x<<1|1]),r1[x<<1]+l1[x<<1|1]);
}
void pushdown(int x,int l,int r){
	int t=r-l+1;
	if(eq0[x]){
		eq0[x<<1]=eq0[x<<1|1]=1;
		get(x<<1,t,0,t,0,t,0,t,0);
		get(x<<1|1,t,0,t,0,t,0,t,0);
		eq0[x]=0;
	}
	if(eq1[x]){
		eq1[x<<1]=eq1[x<<1|1]=1;
		get(x<<1,0,t,0,t,0,t,0,t);
		get(x<<1|1,0,t,0,t,0,t,0,t);
		eq1[x]=0;
	}
	if(re[x]){
		re[x<<1]^=1;
		re[x<<1|1]^=1;
		swap(s0[x<<1],s1[x<<1]);swap(l0[x<<1],l1[x<<1]);
		swap(r0[x<<1],r1[x<<1]);swap(bl0[x<<1],bl1[x<<1]);
		swap(s0[x<<1|1],s1[x<<1|1]);swap(l0[x<<1|1],l1[x<<1|1]);
		swap(r0[x<<1|1],r1[x<<1|1]);swap(bl0[x<<1|1],bl1[x<<1|1]);
		re[x]=0;
	}
}
void build(int x,int l,int r){
	if(l==r){
		int t=a[l];
		get(x,1-t,t,1-t,t,1-t,t,1-t,t);
		return;
	}
	int m=l+r>>1;
	build(x<<1,l,m);
	build(x<<1|1,m+1,r);
	pushup(x);
}
void update(int x,int l,int r,int L,int R,int k){
	if(L<=l&&r<=R){
		int t=r-l+1;
		if(k==0){eq0[x]=1;get(x,t,0,t,0,t,0,t,0);}
		if(k==1){eq1[x]=1;get(x,0,t,0,t,0,t,0,t);}
		if(k==2){
			re[x]^=1;
			swap(s0[x],s1[x]);swap(l0[x],l1[x]);
			swap(r0[x],r1[x]);swap(bl0[x],bl1[x]);
		}
		return ;	
	}
	pushdown(x,l,r);
	int m=l+r>>1;
	if(L<=m)update(x<<1,l,m,L,R,k);
	if(R>m)update(x<<1|1,m+1,r,L,R,k);
	pushup(x);
}
int find1(int x,int l,int r,int L,int R){
	if(L<=l&&r<=R)return s1[x];	
	pushdown(x,l,r);
	int m=l+r>>1,ans=0;
	if(L<=m)ans+=find1(x<<1,l,m,L,R);
	if(R>m)ans+=find1(x<<1|1,m+1,r,L,R);
	return ans;
}
int findb1(int x,int l,int r,int L,int R){
	if(L<=l&&r<=R)return bl1[x];	
	pushdown(x,l,r);
	int m=l+r>>1,ans=0;
	if(L<=m)ans=max(ans,findb1(x<<1,l,m,L,R));
	if(R>m)ans=max(ans,findb1(x<<1|1,m+1,r,L,R));
	return ans;
}
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;++i)
		cin>>a[i];
	build(1,1,n);
	for(int i=1;i<=n;++i){
		print(1,1,n);
		cin>>f>>x>>y;
		++x,++y;
		if(f<3)update(1,1,n,x,y,f);
		else if(f==3) cout<<find1(1,1,n,x,y)<<'\n';
		else cout<<findb1(1,1,n,x,y)<<'\n';
	}
	return 0;
}

print是调试用的,用来输出整个树.

2023/7/17 21:43
加载中...