zoukankan      html  css  js  c++  java
  • 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
    ",chaxun(1,1,n,a,b));
    		else
    		{
    			ans=maxr=0;chaxun4(1,1,n,a,b);
    			printf("%d
    ",ans);
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    快速创建一个 Servlet 项目(1)
    快速创建一个 Servlet 项目(2)
    多级派生情况下派生类的构造函数
    最近看了点C++,分享一下我的进度吧!
    进程同步&进程间通信
    multiprocess模块
    进程
    网络编程之socket
    网络通信原理
    网络通信的流程 | 初始socket
  • 原文地址:https://www.cnblogs.com/1124828077ccj/p/12267170.html
Copyright © 2011-2022 走看看