求调
查看原帖
求调
549131
Eous楼主2024/7/18 09:01
#include<bits/stdc++.h>
using namespace std;
int const maxn=1e5+10;
struct node{
	int l,r,cnt[2],sum[2],suml[2],sumr[2];
	bool lazy[3];
	/*
	cnt[0]表示0的个数,cnt[1]表示1的个数
	sum[0]表示最多的连续的0的个数,sum[1]表述最多的连续的1的个数
	suml[0]表示从左边界开始数的0的个数
	sumr[0]表示从左边界开始数的0的个数
	lazy[0]表示全部取0,lazy[1]表示全部取1,lazy[2]表示全部取反
	*/
}tree[maxn<<2];
int n,m;
int op,l,r;
void push_up(node &rt,node &ls,node &rs)
{
	rt.cnt[0]=ls.cnt[0]+rs.cnt[0];
	rt.cnt[1]=ls.cnt[1]+rs.cnt[1];
	rt.sum[0]=max(ls.sumr[0]+rs.suml[0],max(ls.sum[0],rs.sum[0]));
	rt.sum[1]=max(ls.sumr[1]+rs.suml[1],max(ls.sum[1],rs.sum[1]));
	if(ls.cnt[0]==ls.r-ls.l+1)
		rt.suml[0]=ls.r-ls.l+1+rs.suml[0];
	else
		rt.suml[0]=ls.suml[0];
	if(ls.cnt[1]==ls.r-ls.l+1)
		rt.suml[1]=ls.r-ls.l+1+rs.suml[1];
	else
		rt.suml[1]=ls.suml[1];
	if(rs.cnt[0]==rs.r-rs.l+1)
		rt.sumr[0]=rs.r-rs.l+1+ls.sumr[0];
	else
		rt.sumr[0]=rs.sumr[0];
	if(rs.cnt[1]==rs.r-rs.l+1)
		rt.sumr[1]=rs.r-rs.l+1+ls.sumr[1];
	else
		rt.sumr[1]=rs.sumr[1];
}
void push_down(int rt)
{
	int len=tree[rt].r-tree[rt].l+1;
	if(tree[rt].lazy[0])
	{
		tree[rt<<1].cnt[1]=tree[rt<<1].sum[1]=tree[rt<<1].suml[1]=tree[rt<<1].sumr[1]=0;
		tree[rt<<1|1].cnt[1]=tree[rt<<1|1].sum[1]=tree[rt<<1|1].suml[1]=tree[rt<<1|1].sumr[1]=0;
		tree[rt<<1].cnt[0]=tree[rt<<1].sum[0]=tree[rt<<1].suml[0]=tree[rt<<1].sumr[0]=len>>1;
		tree[rt<<1|1].cnt[0]=tree[rt<<1|1].sum[0]=tree[rt<<1|1].suml[0]=tree[rt<<1|1].sumr[0]=len-(len>>1);
		tree[rt<<1].lazy[0]=tree[rt<<1|1].lazy[0]=1;
		tree[rt].lazy[0]=0;
	}
	if(tree[rt].lazy[1])
	{
		tree[rt<<1].cnt[0]=tree[rt<<1].sum[0]=tree[rt<<1].suml[0]=tree[rt<<1].sumr[0]=0;
		tree[rt<<1|1].cnt[0]=tree[rt<<1|1].sum[0]=tree[rt<<1|1].suml[0]=tree[rt<<1|1].sumr[0]=0;
		tree[rt<<1].cnt[1]=tree[rt<<1].sum[1]=tree[rt<<1].suml[1]=tree[rt<<1].sumr[1]=len>>1;
		tree[rt<<1|1].cnt[1]=tree[rt<<1|1].sum[1]=tree[rt<<1|1].suml[1]=tree[rt<<1|1].sumr[1]=len-(len>>1);
		tree[rt<<1].lazy[1]=tree[rt<<1|1].lazy[1]=1;
		tree[rt].lazy[1]=0;
	}
	if(tree[rt].lazy[2])
	{
		swap(tree[rt<<1].cnt[0],tree[rt<<1].cnt[1]);
		swap(tree[rt<<1].sum[0],tree[rt<<1].sum[1]);
		swap(tree[rt<<1].suml[0],tree[rt<<1].suml[1]);
		swap(tree[rt<<1].sumr[0],tree[rt<<1].sumr[1]);
		swap(tree[rt<<1|1].cnt[0],tree[rt<<1|1].cnt[1]);
		swap(tree[rt<<1|1].sum[0],tree[rt<<1|1].sum[1]);
		swap(tree[rt<<1|1].suml[0],tree[rt<<1|1].suml[1]);
		swap(tree[rt<<1|1].sumr[0],tree[rt<<1|1].sumr[1]);
		tree[rt<<1].lazy[2]=tree[rt<<1|1].lazy[2]=1;
		tree[rt].lazy[2]=0;
	}
}
void build(int l,int r,int rt)
{
	tree[rt].l=l;
	tree[rt].r=r;
	if(l==r)
	{
		int tmp;
		cin>>tmp;
		tree[rt].cnt[0]=tree[rt].sum[0]=tree[rt].suml[0]=tree[rt].sumr[0]=(!tmp);
		tree[rt].cnt[1]=tree[rt].sum[1]=tree[rt].suml[1]=tree[rt].sumr[1]=tmp;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,rt<<1);
	build(mid+1,r,rt<<1|1);
	push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
void print(int rt)
{
	int l=tree[rt].l;
	int r=tree[rt].r; 
	if(l==r)
	{
		printf("%d ",tree[rt].cnt[1]);
		return;
	}
	push_down(rt);
	print(rt<<1);
	print(rt<<1|1);
}
void update0(int ql,int qr,int rt)
{
	int l=tree[rt].l;
	int r=tree[rt].r;
	if(ql<=l&&r<=qr)
	{
		tree[rt].lazy[1]=tree[rt].lazy[2]=0;
		tree[rt].lazy[0]=1;
		tree[rt].cnt[0]=tree[rt].sum[0]=tree[rt].suml[0]=tree[rt].sumr[0]=r-l+1;
		tree[rt].cnt[1]=tree[rt].sum[1]=tree[rt].suml[1]=tree[rt].sumr[1]=0;
		return;
	}
	push_down(rt);
	int mid=(l+r)>>1;
	if(ql<=mid)
		update0(ql,qr,rt<<1);
	if(qr>mid)
		update0(ql,qr,rt<<1|1);
	push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
void update1(int ql,int qr,int rt)
{
	int l=tree[rt].l;
	int r=tree[rt].r;
	if(ql<=l&&r<=qr)
	{
		tree[rt].lazy[0]=tree[rt].lazy[2]=0;
		tree[rt].lazy[1]=1;
		tree[rt].cnt[1]=tree[rt].sum[1]=tree[rt].suml[1]=tree[rt].sumr[1]=r-l+1;
		tree[rt].cnt[0]=tree[rt].sum[0]=tree[rt].suml[0]=tree[rt].sumr[0]=0;
		return;
	}
	push_down(rt);
	int mid=(l+r)>>1;
	if(ql<=mid)
		update1(ql,qr,rt<<1);
	if(qr>mid)
		update1(ql,qr,rt<<1|1);
	push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
void update2(int ql,int qr,int rt)
{
	int l=tree[rt].l;
	int r=tree[rt].r;
	if(ql<=l&&r<=qr)
	{
		tree[rt].lazy[2]=1;
		swap(tree[rt].cnt[0],tree[rt].cnt[1]);
		swap(tree[rt].sum[0],tree[rt].sum[1]);
		swap(tree[rt].suml[0],tree[rt].suml[1]);
		swap(tree[rt].sumr[0],tree[rt].sumr[1]);
		return;
	}
	push_down(rt);
	int mid=(l+r)>>1;
	if(ql<=mid)
		update2(ql,qr,rt<<1);
	if(qr>mid)
		update2(ql,qr,rt<<1|1);
	push_up(tree[rt],tree[rt<<1],tree[rt<<1|1]);
}
int query1(int ql,int qr,int rt)//查1的个数
{
	int l=tree[rt].l;
	int r=tree[rt].r;
	if(ql<=l&&r<=qr)
		return tree[rt].cnt[1];
	push_down(rt);
	int mid=(l+r)>>1,ret=0;
	if(ql<=mid)
		ret+=query1(ql,qr,rt<<1);
	if(qr>mid)
		ret+=query1(ql,qr,rt<<1|1);
	return ret;
}
node query2(int ql,int qr,int rt)
{
	int l=tree[rt].l;
	int r=tree[rt].r;
	if(ql<=l&&r<=qr)
		return tree[rt];
	push_down(rt);
	int mid=(l+r)>>1;
	if(ql<=mid&&mid<qr)
	{
		node x=query2(ql,qr,rt<<1),y=query2(ql,qr,rt<<1|1),ret;
		push_up(ret,x,y);
		ret.l=x.l,ret.r=y.r;
		return ret;
	}
	else if(ql<=mid)
		return query2(ql,qr,rt<<1);
	else if(qr>mid)
		return query2(ql,qr,rt<<1|1);
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n>>m;
	build(1,n,1);
	while(m--)
	{
		cin>>op>>l>>r;
		l++,r++;
		switch(op) 
		{
			case 0:
				update0(l,r,1);
				break;
			case 1:
				update1(l,r,1);
				break;
			case 2:
				update2(l,r,1);
				break;
			case 3:
				cout<<query1(l,r,1)<<endl;
				break;
			case 4:
				cout<<query2(l,r,1).sum[1]<<endl;
				break;
		}
		print(1);
		cout<<endl;
	}
	return 0;
}
2024/7/18 09:01
加载中...