dtoi1278 序列操作 operation

题意:

     

题解:

     这题其实就是一道线段树的基础应用题,只不过代码稍稍有点长。

     本题只需要维护0/1的个数,左边和右边最长连续0/1的个数,总的最大的0/1的个数。取反操作就是把上述维护的值0/1互换,其余的直接修改。

     注意细节,难度并不大。

 
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cstdlib>
using namespace std;
int n,m,s[100002],op,a,b,ans,maxr;
typedef struct{
	int sum0,sum1,lef0,lef1,righ0,righ1,max0,max1;
	int f1;bool f2;
}P;
P p[400002];
void hb(int root,int begin,int end,int mid){
	p[root].sum0=p[root*2].sum0+p[root*2+1].sum0;
	p[root].sum1=p[root*2].sum1+p[root*2+1].sum1;
	if (p[root*2].lef0==mid-begin+1)p[root].lef0=p[root*2].lef0+p[root*2+1].lef0;
	else p[root].lef0=p[root*2].lef0;
	if (p[root*2].lef1==mid-begin+1)p[root].lef1=p[root*2].lef1+p[root*2+1].lef1;
	else p[root].lef1=p[root*2].lef1;
	if (p[root*2+1].righ0==end-mid)p[root].righ0=p[root*2+1].righ0+p[root*2].righ0;
	else p[root].righ0=p[root*2+1].righ0;
	if (p[root*2+1].righ1==end-mid)p[root].righ1=p[root*2+1].righ1+p[root*2].righ1;
	else p[root].righ1=p[root*2+1].righ1;
	p[root].max1=max(max(p[root*2].max1,p[root*2+1].max1),p[root*2].righ1+p[root*2+1].lef1);
    p[root].max0=max(max(p[root*2].max0,p[root*2+1].max0),p[root*2].righ0+p[root*2+1].lef0);
}
void pushdown(int root,int begin,int end,int mid){
	if (p[root].f1!=-1)
	{
		if (!p[root].f1)
		{	
		    p[root*2].lef0=p[root*2].max0=p[root*2].righ0=p[root*2].sum0=mid-begin+1;
		    p[root*2].lef1=p[root*2].max1=p[root*2].righ1=p[root*2].sum1=0;
		    p[root*2+1].lef0=p[root*2+1].max0=p[root*2+1].righ0=p[root*2+1].sum0=end-mid;
		    p[root*2+1].lef1=p[root*2+1].max1=p[root*2+1].righ1=p[root*2+1].sum1=0;
	    }
	    else
	    {
	    	p[root*2].lef1=p[root*2].max1=p[root*2].righ1=p[root*2].sum1=mid-begin+1;
		    p[root*2].lef0=p[root*2].max0=p[root*2].righ0=p[root*2].sum0=0;
		    p[root*2+1].lef1=p[root*2+1].max1=p[root*2+1].righ1=p[root*2+1].sum1=end-mid;
		    p[root*2+1].lef0=p[root*2+1].max0=p[root*2+1].righ0=p[root*2+1].sum0=0;
		}
		p[root*2].f1=p[root*2+1].f1=p[root].f1;
		p[root*2].f2=p[root*2+1].f2=0;p[root].f1=-1;
	}
	if (p[root].f2)
	{
		swap(p[root*2].lef1,p[root*2].lef0);
		swap(p[root*2].righ1,p[root*2].righ0);
		swap(p[root*2].max1,p[root*2].max0);
		swap(p[root*2].sum1,p[root*2].sum0);
		swap(p[root*2+1].lef1,p[root*2+1].lef0);
		swap(p[root*2+1].righ1,p[root*2+1].righ0);
		swap(p[root*2+1].max1,p[root*2+1].max0);
		swap(p[root*2+1].sum1,p[root*2+1].sum0);
		p[root*2].f2=!p[root*2].f2;
		p[root*2+1].f2=!p[root*2+1].f2;
		p[root].f2=0;
	}
}
void build(int root,int begin,int end){
	if (begin==end)
	{
		p[root].sum0=p[root].lef0=p[root].righ0=p[root].max0=!s[begin];
		p[root].sum1=p[root].lef1=p[root].righ1=p[root].max1=s[begin];
		p[root].f1=-1;p[root].f2=0;
		return;
	}
	int mid=(begin+end)/2;
	build(root*2,begin,mid);build(root*2+1,mid+1,end);
	p[root].f1=-1;p[root].f2=0;hb(root,begin,end,mid);
}
void gengxin(int root,int begin,int end,int begin2,int end2){
	if (begin>end2 || end<begin2)return;
	if (begin>=begin2 && end<=end2)
	{
		if (!op)
		{
			p[root].f1=0;p[root].f2=0;
			p[root].lef0=p[root].max0=p[root].righ0=p[root].sum0=end-begin+1;
			p[root].lef1=p[root].max1=p[root].righ1=p[root].sum1=0;
		}
		else if (op==1)
		{
			p[root].f1=1;p[root].f2=0;
			p[root].lef1=p[root].max1=p[root].righ1=p[root].sum1=end-begin+1;
			p[root].lef0=p[root].max0=p[root].righ0=p[root].sum0=0;
		}
		else
		{
			p[root].f2=!p[root].f2;
			swap(p[root].lef1,p[root].lef0);
			swap(p[root].righ1,p[root].righ0);
			swap(p[root].max1,p[root].max0);
			swap(p[root].sum1,p[root].sum0);
		}
		return;
	}
	int mid=(begin+end)/2;pushdown(root,begin,end,mid);
	gengxin(root*2,begin,mid,begin2,end2);
	gengxin(root*2+1,mid+1,end,begin2,end2);
	hb(root,begin,end,mid);
}
int chaxun(int root,int begin,int end,int begin2,int end2){
	if (begin>end2 || end<begin2)return 0;
	if (begin>=begin2 && end<=end2)return p[root].sum1;
	int mid=(begin+end)/2;pushdown(root,begin,end,mid);
	return chaxun(root*2,begin,mid,begin2,end2)+chaxun(root*2+1,mid+1,end,begin2,end2);
}
void chaxun4(int root,int begin,int end,int begin2,int end2){
	if (begin>end2 || end<begin2)return;
	if (begin>=begin2 && end<=end2)
	{
		ans=max(max(maxr+p[root].lef1,p[root].max1),ans);
		if (p[root].righ1==end-begin+1)maxr+=p[root].righ1;
		else maxr=p[root].righ1;
		return;
	}
	int mid=(begin+end)/2;pushdown(root,begin,end,mid);
	chaxun4(root*2,begin,mid,begin2,end2);
	chaxun4(root*2+1,mid+1,end,begin2,end2);
}
int main()
{
	scanf("%d%d",&n,&m);memset(p,0,sizeof(p));
	for (int i=1;i<=n;i++)scanf("%d",&s[i]);
	build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&op,&a,&b);a++;b++;
		if (op<=2)gengxin(1,1,n,a,b);
		else if (op==3)printf("%d\n",chaxun(1,1,n,a,b));
		else
		{
			ans=maxr=0;chaxun4(1,1,n,a,b);
			printf("%d\n",ans);
		}
	}
	return 0;
}
posted @ 2020-02-05 23:00  1124828077ccj  阅读(341)  评论(0编辑  收藏  举报