MnZn 线段树求调
查看原帖
MnZn 线段树求调
1031393
to_laz楼主2024/5/23 13:33
#include<bits/stdc++.h>
#define N 100005
#define ls p<<1
#define rs p<<1|1
using namespace std;
struct node{
	int len;
	int sum,sum1,sum0;
	int tag,rev;
	int lmax1,rmax1,lmax0,rmax0;
}tree[N<<2];
int n,m,a[N];
void pushup(int p){
	tree[p].sum=tree[ls].sum+tree[rs].sum;
	tree[p].lmax1=(tree[ls].lmax1==tree[ls].len?tree[ls].len+tree[rs].lmax1:tree[ls].lmax1);
	tree[p].rmax1=(tree[rs].rmax1==tree[rs].len?tree[rs].len+tree[ls].rmax1:tree[rs].lmax1);
	tree[p].sum1=max(max(tree[ls].sum1,tree[rs].sum1),tree[ls].rmax1+tree[rs].lmax1);
	tree[p].lmax0=(tree[ls].lmax0==tree[ls].len?tree[ls].len+tree[rs].lmax0:tree[ls].lmax0);
	tree[p].rmax0=(tree[rs].rmax0==tree[rs].len?tree[rs].len+tree[ls].rmax0:tree[rs].lmax0);
	tree[p].sum0=max(max(tree[ls].sum0,tree[rs].sum0),tree[ls].rmax0+tree[rs].lmax0);
}
void build(int p,int l,int r){
	tree[p].tag=0,tree[p].rev=0,tree[p].len=r-l+1;
	if(l==r){
		tree[p].sum=tree[p].lmax1=tree[p].rmax1=tree[p].sum1=(a[l]==1);
		tree[p].lmax0=tree[p].rmax0=tree[p].sum0=(a[l]==0);
		return;
	}
	int mid=(l+r)>>1;
	build(ls,l,mid);build(rs,mid+1,r);
	pushup(p);
	return;
}
void addtag(int p,int k){
	if(k==1){
		tree[p].tag=1,tree[p].rev=0;
		tree[p].sum=tree[p].lmax1=tree[p].rmax1=tree[p].sum1=0;
		tree[p].sum0=tree[p].lmax0=tree[p].rmax0=tree[p].len;
	}
	if(k==2){
		tree[p].tag=2,tree[p].rev=0;
		tree[p].sum=tree[p].lmax1=tree[p].rmax1=tree[p].sum1=tree[p].len;
		tree[p].sum0=tree[p].lmax0=tree[p].rmax0=0;
	}
	if(k==3){
		tree[p].sum=tree[p].len-tree[p].sum;
		swap(tree[p].sum1,tree[p].sum0);
		swap(tree[p].lmax1,tree[p].lmax0);
		swap(tree[p].rmax1,tree[p].rmax0);
		tree[p].rev^=1;
	}
}
void pushdown(int p){
	if(tree[p].tag==1){//全0
		tree[ls].sum=tree[ls].lmax1=tree[ls].rmax1=tree[ls].sum1=0;
		tree[ls].sum0=tree[ls].lmax0=tree[ls].rmax0=tree[ls].len;
		tree[rs].sum=tree[rs].lmax1=tree[rs].rmax1=tree[rs].sum1=0;
		tree[rs].sum0=tree[rs].lmax0=tree[rs].rmax0=tree[rs].len;
		tree[ls].tag=1,tree[ls].rev=0;
		tree[rs].tag=1,tree[rs].rev=0;
		tree[p].rev=0,tree[p].tag=0;
	}
	if(tree[p].tag==2){//全1
		tree[ls].sum=tree[ls].lmax1=tree[ls].rmax1=tree[ls].sum1=tree[ls].len;
		tree[ls].sum0=tree[ls].lmax0=tree[ls].rmax0=0;
		tree[rs].sum=tree[rs].lmax1=tree[rs].rmax1=tree[rs].sum1=tree[rs].len;
		tree[rs].sum0=tree[rs].lmax0=tree[rs].rmax0=0;
		tree[ls].tag=1,tree[ls].rev=0;
		tree[rs].tag=1,tree[rs].rev=0;
		tree[p].rev=0,tree[p].tag=0;
	}
	if(tree[p].rev){//翻转
		tree[ls].sum=tree[ls].len-tree[ls].sum;
		swap(tree[ls].sum1,tree[ls].sum0);
		swap(tree[ls].lmax1,tree[ls].lmax0);
		swap(tree[ls].rmax1,tree[ls].rmax0);
		if(tree[ls].tag==1) tree[ls].tag=2;
		else if(tree[ls].tag==2) tree[ls].tag=1;
		else tree[ls].rev^=1;
		tree[rs].sum=tree[rs].len-tree[rs].sum;
		swap(tree[rs].sum1,tree[rs].sum0);
		swap(tree[rs].lmax1,tree[rs].lmax0);
		swap(tree[rs].rmax1,tree[rs].rmax0);
		if(tree[rs].tag==1) tree[rs].tag=2;
		else if(tree[rs].tag==2) tree[rs].tag=1;
		else tree[rs].rev^=1;
		tree[p].rev=0;
	}
	return;
}
void update(int p,int l,int r,int L,int R,int k){
	pushdown(p);
	if(l>=L&&r<=R){
		addtag(p,k);
		return;
	}
	if(l>R||r<L) return;
	int mid=(l+r)>>1;
	update(ls,l,mid,L,R,k);update(rs,mid+1,r,L,R,k);
	pushup(p);
	return;
}
int querysum(int p,int l,int r,int L,int R){
	pushdown(p);
	if(l>=L&&r<=R) return tree[p].sum;
	if(l>R||r<L) return 0;
	int mid=(l+r)>>1;
	return querysum(ls,l,mid,L,R)+querysum(rs,mid+1,r,L,R);
}
int querylink(int p,int l,int r,int L,int R){
	pushdown(p);
	if(l==L&&r==R) return tree[p].sum1;
	if(l>R||r<L) return 0;
	int mid=(l+r)>>1;
	if(r<=mid) return querylink(ls,l,mid,L,R);
	else if(l>mid) return querylink(rs,mid+1,r,L,R);
	else return max(max(querylink(ls,l,mid,L,mid),querylink(rs,mid+1,r,mid+1,R)),min(tree[rs].lmax1,r-mid)+min(tree[ls].rmax1,mid-l+1));
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	while(m--){
		int op,l,r;
		cin>>op>>l>>r;
		switch(op){
			case 0:update(1,1,n,l+1,r+1,1);break;
			case 1:update(1,1,n,l+1,r+1,2);break;
			case 2:update(1,1,n,l+1,r+1,3);break;
			case 3:cout<<querysum(1,1,n,l+1,r+1)<<'\n';break;
			default:cout<<querylink(1,1,n,l+1,r+1)<<'\n';break;
		}
	}
	return 0;
}
2024/5/23 13:33
加载中...