• HDU 3397 Sequence operation


    花了一秒钟时间构思,写了好几天。弱。

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    #include <set>
    #include <map>
    #include <string>
    #include <math.h>
    #include <stdlib.h>
    #include <time.h>
    using namespace std;
     
    const int maxn=100000+10;
    int T,N,Q,ans;
    struct SegTree
    {
        int zero;//零的个数
        int one;//一的个数
        int lsum;//从左边开始的最长连续的1的长度
        int rsum;//从右边开始的最长连续的1的长度
        int msum;//这段区间连续最长的1的长度
     
        int Lsum;//从左边开始的最长连续的0的长度
        int Rsum;//从右边开始的最长连续的0的长度
        int Msum;//这段区间连续最长的0的长度
     
        int f;
     
    }segTree[maxn*4];
     
    void tra1(int rt,int len)//变0
    {
        segTree[rt].zero=len;
        segTree[rt].one=0;
        segTree[rt].lsum=0;
        segTree[rt].rsum=0;
        segTree[rt].msum=0;
        segTree[rt].Lsum=len;
        segTree[rt].Rsum=len;
        segTree[rt].Msum=len;
    }
     
    void tra2(int rt,int len)//变1
    {
        segTree[rt].zero=0;
        segTree[rt].one=len;
        segTree[rt].lsum=len;
        segTree[rt].rsum=len;
        segTree[rt].msum=len;
        segTree[rt].Lsum=0;
        segTree[rt].Rsum=0;
        segTree[rt].Msum=0;
    }
     
    void Swap(int rt)
    {
        swap(segTree[rt].zero,segTree[rt].one);
        swap(segTree[rt].lsum,segTree[rt].Lsum);
        swap(segTree[rt].rsum,segTree[rt].Rsum);
        swap(segTree[rt].msum,segTree[rt].Msum);
    }
     
    void pushUp(int rt,int len)
    {
        //确定零的个数
        segTree[rt].zero=segTree[2*rt].zero+segTree[2*rt+1].zero;
         
        //确定一的个数
        segTree[rt].one=segTree[2*rt].one+segTree[2*rt+1].one;
     
        //确定从左边开始最长连续1的长度
        if(segTree[2*rt].msum==len-len/2)
            segTree[rt].lsum=segTree[2*rt].lsum+segTree[2*rt+1].lsum;
        else
            segTree[rt].lsum=segTree[2*rt].lsum;
     
        //确定从右边开始最长连续1的长度
        if(segTree[2*rt+1].rsum==len/2)
            segTree[rt].rsum=segTree[2*rt].rsum+segTree[2*rt+1].rsum;
        else
            segTree[rt].rsum=segTree[2*rt+1].rsum;
     
        //确定这段区间连续最长的1的长度
        segTree[rt].msum=max(segTree[2*rt].msum,segTree[2*rt+1].msum);
        segTree[rt].msum=max(segTree[rt].msum,segTree[2*rt].rsum+segTree[2*rt+1].lsum);
     
     
        //确定从左边开始最长连续0的长度
        if(segTree[2*rt].Msum==len-len/2)
            segTree[rt].Lsum=segTree[2*rt].Lsum+segTree[2*rt+1].Lsum;
        else
            segTree[rt].Lsum=segTree[2*rt].Lsum;
     
        //确定从右边开始最长连续0的长度
        if(segTree[2*rt+1].Rsum==len/2)
            segTree[rt].Rsum=segTree[2*rt].Rsum+segTree[2*rt+1].Rsum;
        else
            segTree[rt].Rsum=segTree[2*rt+1].Rsum;
     
        //确定这段区间连续最长的0的长度
        segTree[rt].Msum=max(segTree[2*rt].Msum,segTree[2*rt+1].Msum);
        segTree[rt].Msum=max(segTree[rt].Msum,segTree[2*rt].Rsum+segTree[2*rt+1].Lsum);
     
    }
     
    void pushDown(int rt,int len)
    {
        if(segTree[rt].f==0)
        {
            segTree[2*rt].f=segTree[2*rt+1].f=0;
     
            tra1(2*rt,len-len/2);
            tra1(2*rt+1,len/2);
        }
     
        else if(segTree[rt].f==1)
        {
            segTree[2*rt].f=segTree[2*rt+1].f=1;
     
            tra2(2*rt,len-len/2);
            tra2(2*rt+1,len/2);
        }
     
        else
        {
            Swap(2*rt);
            if(segTree[2*rt].f==0) segTree[2*rt].f=1;
            else if(segTree[2*rt].f==1) segTree[2*rt].f=0;
            else if(segTree[2*rt].f==-1) segTree[2*rt].f=2;
            else segTree[2*rt].f=-1;
    
            Swap(2*rt+1);
            if(segTree[2*rt+1].f==0) segTree[2*rt+1].f=1;
            else if(segTree[2*rt+1].f==1) segTree[2*rt+1].f=0;
            else if(segTree[2*rt+1].f==-1) segTree[2*rt+1].f=2;
            else segTree[2*rt+1].f=-1;
        }
        segTree[rt].f=-1;
    }
     
    void build(int l,int r,int rt)
    {
        segTree[rt].f=-1;
     
        if(l==r)
        {
            int x;
            scanf("%d",&x);
            if(x==0) tra1(rt,1);
            else if(x==1) tra2(rt,1);
            return;
        }
         
        int m=(l+r)/2;
        build(l,m,2*rt);
        build(m+1,r,2*rt+1);
     
        pushUp(rt,r-l+1);
    }
     
    void update(int L,int R,int f,int Xor,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
        {
            if(f==-1)//第二种操作
            {
                Swap(rt);
                if(segTree[rt].f==1) segTree[rt].f=0;
                else if(segTree[rt].f==0) segTree[rt].f=1;
                else if(segTree[rt].f==-1)  segTree[rt].f=2;
                else segTree[rt].f=-1;
            }
     
            else //第零种,第一种操作
            {
                if(f==0) tra1(rt,r-l+1);
                else tra2(rt,r-l+1);    
                segTree[rt].f=f;
            }
            return;
        }
    
        if(segTree[rt].f!=-1)
            pushDown(rt,r-l+1);
     
        int m=(l+r)/2;
        if(L<=m) update(L,R,f,Xor,l,m,2*rt);
        if(R>m) update(L,R,f,Xor,m+1,r,2*rt+1);
     
        pushUp(rt,r-l+1);
    }
     
    int quary1(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&r<=R)
            return segTree[rt].one;
     
        if(segTree[rt].f!=-1)
            pushDown(rt,r-l+1);
    
        int m=(l+r)/2;
        int res=0;
        if(L<=m) res+=quary1(L,R,l,m,2*rt);
        if(R>m) res+=quary1(L,R,m+1,r,2*rt+1);
        pushUp(rt,r-l+1);
        return res;
    }
     
    int quary2(int L,int R,int l,int r,int rt)
    {
        if(L<=l&&R>=r) return segTree[rt].msum;
        if(segTree[rt].f!=-1) pushDown(rt,r-l+1);
    
        int m=(l+r)/2;
        if(R<=m) return quary2(L,R,l,m,2*rt);
        else if(L>m) return quary2(L,R,m+1,r,2*rt+1);
        else
        {
            int Q1=quary2(L,R,l,m,2*rt);
            int Q2=quary2(L,R,m+1,r,2*rt+1);
     
            int E=max(Q1,Q2);
     
            int Min1=min(segTree[2*rt].rsum,m-L+1);
            int Min2=min(segTree[2*rt+1].lsum,R-m);
     
            E=max(E,Min1+Min2);
            return E;
        }
        pushUp(rt,r-l+1);
    }
     
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&N,&Q);
            build(1,N,1);
            for(int i=1;i<=Q;i++)
            {
                int op,a,b;
                scanf("%d%d%d",&op,&a,&b);
                a++;b++;
     
                if(op==0) update(a,b,0,-1,1,N,1);
                if(op==1) update(a,b,1,-1,1,N,1);
                if(op==2) update(a,b,-1,1,1,N,1);
                if(op==3) printf("%d
    ", quary1(a,b,1,N,1));
                if(op==4) printf("%d
    ",quary2(a,b,1,N,1));
            }
        }
        return 0;
    }
  • 相关阅读:
    日常护理常识以及化妆品的选购 健康程序员,至尚生活!
    六个动作帮你甩掉小肚腩 健康程序员,至尚生活!
    便秘有妙招 轻松摆脱便秘烦恼 健康程序员,至尚生活!
    推荐一个单干网赚好站!BUXJOB 健康程序员,至尚生活!
    橙子减肥法:好吃快速成为瘦美人 健康程序员,至尚生活!
    mssql获取各种形式的时间
    mssql 事务的一个例子
    《深入浅出WPF》笔记——事件篇
    《深入浅出WPF》笔记——绘画与动画
    WPF深入浅出笔记
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5014196.html
Copyright © 2020-2023  润新知