MnZn刚学线段树 求调
查看原帖
MnZn刚学线段树 求调
656046
SW_YM楼主2024/5/24 20:34
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e6+10;
struct Node
{
	int total,lm0,lm1,rm0,rm1,sm0,sm1,lzc,lza,len;
}sum[MAXN];
int num[MAXN],n,m;
#define rs rt<<1|1
#define ls rt<<1

void maintain(int rt)
{
	sum[rt].total=sum[ls].total+sum[rs].total;
	sum[rt].lm0=sum[ls].total==0?sum[ls].lm0+sum[rs].lm0:sum[ls].lm0;
	sum[rt].lm1=sum[ls].total==sum[ls].len?sum[ls].lm1+sum[rs].lm1:sum[ls].lm1;
	sum[rt].rm0=sum[rs].total==0?sum[ls].rm0+sum[rs].rm0:sum[rs].rm0;
	sum[rt].rm1=sum[rs].total==sum[rs].len?sum[ls].rm1+sum[rs].rm1:sum[rs].rm1;
	sum[rt].sm0=max(max(sum[ls].sm0,sum[rs].sm0),sum[ls].rm0+sum[rs].lm0);
	sum[rt].sm1=max(max(sum[ls].sm1,sum[rs].sm1),sum[ls].rm1+sum[rs].lm1);
	return;
}
void build(int rt,int l,int r)
{
	sum[rt].lzc=-1;
	sum[rt].lza=0;
	sum[rt].len=r-l+1;
	if(l==r)
	{
		sum[rt].total=sum[rt].lm1=sum[rt].rm1=sum[rt].sm1=num[l];
		sum[rt].lm0=sum[rt].rm0=sum[rt].sm0=sum[rt].len-sum[rt].total;
		return;
	}
	int mid=l+r>>1;
	build(ls,l,mid);
	build(rs,mid+1,r);
	maintain(rt);
	return;
}
void pushdown(int rt,int l,int mid,int r)
{
	if(sum[rt].lzc!=-1)
	{
		sum[ls].lza=sum[rs].lza=0;
		sum[ls].total=sum[ls].lm1=sum[ls].rm1=sum[ls].sm1=sum[ls].len*sum[rt].lzc;
		sum[rs].total=sum[rs].lm1=sum[rs].rm1=sum[rs].sm1=sum[rs].len*sum[rt].lzc;
		sum[ls].lm0=sum[ls].rm0=sum[ls].sm0=sum[ls].len-sum[ls].total;
		sum[rs].lm0=sum[rs].rm0=sum[rs].sm0=sum[rs].len-sum[rs].total;
		sum[ls].lzc=sum[rs].lzc=sum[rt].lzc;
		sum[rt].lzc=-1;
	}
	if(sum[rt].lza)
	{
		sum[ls].total=sum[ls].len-sum[ls].total;
		sum[rs].total=sum[rs].len-sum[ls].total;
		swap(sum[ls].lm0,sum[ls].lm1);
		swap(sum[rs].lm0,sum[rs].lm1);
		swap(sum[ls].rm0,sum[ls].rm1);
		swap(sum[rs].rm0,sum[rs].rm1);
		swap(sum[ls].sm0,sum[ls].sm1);
		swap(sum[rs].sm0,sum[rs].sm1);
		if(sum[ls].lzc!=-1)sum[ls].lzc^=1;
		else sum[ls].lza^=1;
		if(sum[rs].lzc!=-1)sum[rs].lzc^=1;
		else sum[rs].lza^=1;
		sum[rt].lza=0;
	}
	return;
}
void cover(int rt,int l,int r,int ql,int qr,int w)
{
	if(ql>r||qr<l)return;
	int mid=l+r>>1;
	pushdown(rt,l,mid,r);
	if(ql<=l&&r<=qr)
	{
		sum[rt].total=sum[rt].lm1=sum[rt].rm1=sum[rt].sm1=sum[rt].len*w;
		sum[rt].lm0=sum[rt].rm0=sum[rt].sm0=sum[rt].len-sum[rt].total;
		sum[rt].lzc=w;
		sum[rt].lza=0;
		return;
	}

	cover(ls,l,mid,ql,qr,w);
	cover(rs,mid+1,r,ql,qr,w);
	maintain(rt);
	return;
}
void add(int rt,int l,int r,int ql,int qr,int w)
{
	if(ql>r||qr<l)return;
	int mid=l+r>>1;
	pushdown(rt,l,mid,r);
	if(ql<=l&&r<=qr)
	{
		sum[rt].total=sum[rt].len-sum[rt].total;
		swap(sum[rt].lm0,sum[rt].lm1);
		swap(sum[rt].rm0,sum[rt].rm1);
		swap(sum[rt].sm0,sum[rt].sm1);
		if(sum[rt].lzc!=-1)sum[rt].lzc^=1;
		else sum[rt].lza^=1;
		return;
	}
	add(ls,l,mid,ql,qr,w);
	add(rs,mid+1,r,ql,qr,w);
	maintain(rt);
	return ;
}
Node query(int rt,int l,int r,int ql,int qr)
{
//	if(ql>r||qr<l)
//	{
//		Node x={0,0,0,0,0,0,0,-1,2,0};
//		return x;
//	}
	int mid=l+r>>1;
	pushdown(rt,l,mid,r);
	if(ql<=l&&r<=qr)return sum[rt];
	if(qr<=mid)return query(ls,l,mid,ql,qr);
	else if(ql>mid)return query(rs,mid+1,r,ql,qr);
	else
	{
		Node left=query(ls,l,mid,ql,qr),right=query(rs,mid+1,r,ql,qr);
		int tot=left.total+right.total;
		int nlm0=left.total==0?left.lm0+right.lm0:left.lm0;
		int nlm1=left.total==left.len?left.lm1+right.lm1:left.lm1;
		int nrm0=right.total==0?left.rm0+right.rm0:right.rm0;
		int nrm1=right.total==right.len?left.rm1+right.rm1:right.rm1;
		int nsm0=max(max(left.sm0,right.sm0),left.rm0+right.lm0);
		int nsm1=max(max(left.sm1,right.sm1),left.rm1+right.lm1);
		return {tot,nlm0,nlm1,nrm0,nrm1,nsm0,nsm1,-1,0,0};
	}
}
int main()
{
	ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>num[i];
	}
	build(1,1,n);
	while(m--)
	{
		int oper,l,r;
		cin>>oper>>l>>r;
		l++;r++;
		if(oper==0)cover(1,1,n,l,r,0);
		else if(oper==1)cover(1,1,n,l,r,1);
		else if(oper==2)add(1,1,n,l,r,1);
		else if(oper==3)cout<<query(1,1,n,l,r).total<<'\n';
		else if(oper==4)cout<<query(1,1,n,l,r).sm1<<'\n';
	}
	return 0;
}
2024/5/24 20:34
加载中...