zoukankan      html  css  js  c++  java
  • hdu 3397 Sequence operation

    Sequence operation

    Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 4393    Accepted Submission(s): 1272


    Problem Description
    lxhgww got a sequence contains n characters which are all '0's or '1's.
    We have five operations here:
    Change operations:
    0 a b change all characters into '0's in [a , b]
    1 a b change all characters into '1's in [a , b]
    2 a b change all '0's into '1's and change all '1's into '0's in [a, b]
    Output operations:
    3 a b output the number of '1's in [a, b]
    4 a b output the length of the longest continuous '1' string in [a , b]
     
    Input
    T(T<=10) in the first line is the case number.
    Each case has two integers in the first line: n and m (1 <= n , m <= 100000).
    The next line contains n characters, '0' or '1' separated by spaces.
    Then m lines are the operations:
    op a b: 0 <= op <= 4 , 0 <= a <= b < n.
     
    Sample Input
    1
    10 10
    0 0 0 1 1 0 1 0 1 1
    1 0 2
    3 0 5
    2 2 2
    4 0 4
    0 3 6
    2 3 7
    4 2 8
    1 0 5
    0 5 6
    3 3 9
    Sample Output
    5
    2
    6
    5
    Output
    For each output operation , output the result.
     
     
    hdu3911的变形,线段树的合并+延迟标记。
    题意:
        给你5总操作
    x l,r
    x==0 将区间[l,r]全部置为0
    x==1 将区间[l,r]全部置为1
    x==2 将区间[l,r]0的置换为1, 1的置换为0
    ~~~~~~~~~~~(华丽的分割线)
    x==3 输出区间[l,r] 1的个数
    x==4 输出区间[l,r] 最长的连续的 1 的个数
     
    思路:hdu3911的变形,建议先做3911试试手。
    变量color为延迟标记
    当color为 ZERO   代表该区间全部都是0 ,
          那么其区间的左端点 右端点的值为0,而且统计1的三个变量的值都为0: one_max , one_lmax, one_rmax;
    当color为 ONE     代表该区间全部都是1,同理可知。
    当color为 HH       代码该区间的值是置反的。则统计1的三个变量,和统计0的三个变量进行交换。不理解,建议动手画画图。
     
    在向下更新的时候,HH的情况也需要特别的注意。
    如果该区间color的值原来为ZERO,那么又遇到了HH,那么变成ONE就可以了。
    如果该区间color的值原来是ONE,  那么又遇到了HH,就变成ZERO.
    如果该区间color的值原来是HH ,     那么就要变成0,
    如果该区间color的值原来是0,      那么变成HH。
     
    写了好长的代码, 方法比较笨,时间花销就多了一些。写过最长的代码了,363行。
    我想,在比赛中出现这样的题,那简直就是坑爹。
    其中为了更容易检查错误,采取了一些对齐。和变量的命名修改,和hdu3911有些区别,
    在做hdu3911吃了亏.....
     
    代码:
    #include<stdio.h>
    #define HH 1
    #define ZERO 2
    #define ONE 3
    struct st
    {
        int l,r;
        int lnum,rnum;
        int one_lmax,one_rmax,one_max;
        int zer_lmax,zer_rmax,zer_max;
        int color;
        int sum;
    }f[100002*4];
    int date[100002];
    int max(int x,int y)
    {
        if(x>y)
            return x;
        else return y;
    }
    int min(int x,int y)
    {
        if(x<y)
            return x;
        else return y;
    }
    int Max(int x,int y,int z)
    {
        return max(max(x,y),z);
    }
    void up(struct st *fa,struct st *lll,struct st *rrr)
    {
        fa->lnum=lll->lnum;
        fa->rnum=rrr->rnum;
        fa->sum=lll->sum+rrr->sum;
        if(lll->rnum==0&&rrr->lnum==0)
        {
            fa->zer_lmax=(lll->zer_lmax==(lll->r-lll->l+1))? lll->zer_lmax+rrr->zer_lmax:lll->zer_lmax;
            fa->zer_rmax=(rrr->zer_rmax==(rrr->r-rrr->l+1))? rrr->zer_rmax+lll->zer_rmax:rrr->zer_rmax;
            fa->zer_max =Max(max(fa->zer_lmax,fa->zer_rmax),max(lll->zer_max,rrr->zer_max),lll->zer_rmax+rrr->zer_lmax);
        }
        else 
        {
            fa->zer_lmax=lll->zer_lmax;
            fa->zer_rmax=rrr->zer_rmax;
            fa->zer_max =max(lll->zer_max,rrr->zer_max);
        }
        if(lll->rnum==1&&rrr->lnum==1)
        {
            fa->one_lmax=(lll->one_lmax==(lll->r-lll->l+1))? lll->one_lmax+rrr->one_lmax:lll->one_lmax;
            fa->one_rmax=(rrr->one_rmax==(rrr->r-rrr->l+1))? rrr->one_rmax+lll->one_rmax:rrr->one_rmax;
            fa->one_max =Max(max(fa->one_lmax,fa->one_rmax),max(lll->one_max,rrr->one_max),lll->one_rmax+rrr->one_lmax);
        }
        else 
        {
            fa->one_lmax=lll->one_lmax;
            fa->one_rmax=rrr->one_rmax;
            fa->one_max =max(lll->one_max,rrr->one_max);
        }
    }
    void down(int n)
    {
        int k;
        if(f[n].color==ONE)
        {
            f[n*2].color=f[n].color;
            f[n*2].lnum =1;
            f[n*2].rnum =1;
            f[n*2].one_lmax=f[n*2].r-f[n*2].l+1;
            f[n*2].one_rmax=f[n*2].r-f[n*2].l+1;
            f[n*2].one_max =f[n*2].r-f[n*2].l+1;
            f[n*2].zer_lmax=0;
            f[n*2].zer_rmax=0;
            f[n*2].zer_max =0;
            f[n*2].sum=f[n*2].r-f[n*2].l+1;
    
            f[n*2+1].color=f[n].color;
            f[n*2+1].lnum =1;
            f[n*2+1].rnum =1;
            f[n*2+1].one_lmax=f[n*2+1].r-f[n*2+1].l+1;
            f[n*2+1].one_rmax=f[n*2+1].r-f[n*2+1].l+1;
            f[n*2+1].one_max =f[n*2+1].r-f[n*2+1].l+1;
            f[n*2+1].zer_lmax=0;
            f[n*2+1].zer_rmax=0;
            f[n*2+1].zer_max =0;
            f[n*2+1].sum=f[n*2+1].r-f[n*2+1].l+1;
    
            f[n].color=0;
        }
        else if(f[n].color==ZERO)
        {
            f[n*2].color=f[n].color;
            f[n*2].lnum=0;
            f[n*2].rnum=0;
            f[n*2].one_lmax=0;
            f[n*2].one_max =0;
            f[n*2].one_rmax=0;
            f[n*2].zer_lmax=f[n*2].r-f[n*2].l+1;
            f[n*2].zer_rmax=f[n*2].r-f[n*2].l+1;
            f[n*2].zer_max =f[n*2].r-f[n*2].l+1;
            f[n*2].sum=0;
    
            f[n*2+1].color=f[n].color;
            f[n*2+1].lnum=0;
            f[n*2+1].rnum=0;
            f[n*2+1].one_lmax=0;
            f[n*2+1].one_rmax=0;
            f[n*2+1].one_max =0;
            f[n*2+1].zer_lmax=f[n*2+1].r-f[n*2+1].l+1;
            f[n*2+1].zer_rmax=f[n*2+1].r-f[n*2+1].l+1;
            f[n*2+1].zer_max =f[n*2+1].r-f[n*2+1].l+1;
            f[n*2+1].sum=0;
    
            f[n].color=0;
        }
        else if(f[n].color==HH)
        {
            if(f[n*2].color==ONE)
                f[n*2].color=ZERO;
            else if(f[n*2].color==ZERO)
                f[n*2].color=ONE;
            else if(f[n*2].color==0)
                f[n*2].color=HH;
            else if(f[n*2].color==HH)
                f[n*2].color=0;
            if(f[n*2].lnum==0)
                f[n*2].lnum=1;
            else f[n*2].lnum=0;
            if(f[n*2].rnum==0)
                f[n*2].rnum=1;
            else f[n*2].rnum=0;
    
            if(f[n*2+1].color==ONE)
                f[n*2+1].color=ZERO;
            else if(f[n*2+1].color==ZERO)
                f[n*2+1].color=ONE;
            else if(f[n*2+1].color==0)
                f[n*2+1].color=HH;
            else if(f[n*2+1].color==HH)
                f[n*2+1].color=0;
            if(f[n*2+1].lnum==0)
                f[n*2+1].lnum=1;
            else f[n*2+1].lnum=0;
            if(f[n*2+1].rnum==0)
                f[n*2+1].rnum=1;
            else f[n*2+1].rnum=0;
    
            k=f[n*2].one_lmax;
            f[n*2].one_lmax=f[n*2].zer_lmax;
            f[n*2].zer_lmax=k;
            k=f[n*2].one_max;
            f[n*2].one_max=f[n*2].zer_max;
            f[n*2].zer_max=k;
            k=f[n*2].one_rmax;
            f[n*2].one_rmax=f[n*2].zer_rmax;
            f[n*2].zer_rmax=k;
            f[n*2].sum=f[n*2].r-f[n*2].l+1-f[n*2].sum;
    
            k=f[n*2+1].one_lmax;
            f[n*2+1].one_lmax=f[n*2+1].zer_lmax;
            f[n*2+1].zer_lmax=k;
            k=f[n*2+1].one_max;
            f[n*2+1].one_max=f[n*2+1].zer_max;
            f[n*2+1].zer_max=k;
            k=f[n*2+1].one_rmax;
            f[n*2+1].one_rmax=f[n*2+1].zer_rmax;
            f[n*2+1].zer_rmax=k;
            f[n*2+1].sum=f[n*2+1].r-f[n*2+1].l+1-f[n*2+1].sum;
    
            f[n].color=0;
    
        }
    }
    void build(int l,int r,int n)
    {
        int mid=(l+r)/2;
        f[n].l=l;
        f[n].r=r;
        f[n].color=0;
        if(l==r)
        {
            f[n].lnum=date[l];
            f[n].rnum=date[l];
            if(date[l]==0)
            {
                f[n].zer_lmax=1;
                f[n].zer_rmax=1;
                f[n].zer_max=1;
    
                f[n].one_lmax=0;
                f[n].one_rmax=0;
                f[n].one_max=0;
                f[n].sum=0;
            }
            else if(date[l]==1)
            {
                f[n].zer_lmax=0;
                f[n].zer_rmax=0;
                f[n].zer_max=0;
    
                f[n].one_lmax=1;
                f[n].one_max=1;
                f[n].one_rmax=1;
                f[n].sum=1;
            }
            return;
        }
        build(l,mid,n*2);
        build(mid+1,r,n*2+1);
        up(&f[n],&f[n*2],&f[n*2+1]);
    }
    void xx(int n,int x)
    {
            int k;
            if(x==0)
            {
                f[n].lnum=0;
                f[n].rnum=0;
                f[n].color=ZERO;
                f[n].one_lmax=0;
                f[n].one_rmax=0;
                f[n].one_max =0;
    
                f[n].zer_lmax=f[n].r-f[n].l+1;
                f[n].zer_max =f[n].r-f[n].l+1;
                f[n].zer_rmax=f[n].r-f[n].l+1;
    
                f[n].sum=0;
            }
            else if(x==1)
            {
                f[n].lnum=1;
                f[n].rnum=1;
                f[n].color=ONE;
                f[n].one_lmax=f[n].r-f[n].l+1;
                f[n].one_rmax=f[n].r-f[n].l+1;
                f[n].one_max =f[n].r-f[n].l+1;
    
                f[n].zer_lmax=0;
                f[n].zer_rmax=0;
                f[n].zer_max =0;
    
                f[n].sum=f[n].r-f[n].l+1;
            }
            else if(x==2)
            {
                if(f[n].color==HH)
                {
                    f[n].color=0;
                    f[n].sum=f[n].r-f[n].l+1-f[n].sum;
                }
                else if(f[n].color==ONE)
                {
                    f[n].color=ZERO;
                    f[n].sum=0;
                }
                else if(f[n].color==ZERO)
                {
                    f[n].color=ONE;
                    f[n].sum=f[n].r-f[n].l+1;
                }
                else if(f[n].color==0)
                {
                    f[n].color=HH;
                    f[n].sum=f[n].r-f[n].l+1-f[n].sum;
                }
                if(f[n].lnum==1)
                    f[n].lnum=0;
                else f[n].lnum=1;
                if(f[n].rnum==1)
                    f[n].rnum=0;
                else f[n].rnum=1;
    
                k=f[n].one_lmax;
                f[n].one_lmax=f[n].zer_lmax;
                f[n].zer_lmax=k;
    
                k=f[n].one_max;
                f[n].one_max=f[n].zer_max;
                f[n].zer_max=k;
    
                k=f[n].one_rmax;
                f[n].one_rmax=f[n].zer_rmax;
                f[n].zer_rmax=k;
            }
    }
    void update(int l,int r,int n,int x)
    {
        int mid=(f[n].l+f[n].r)/2;
        if(f[n].l==l&&f[n].r==r)
        {
            xx(n,x);
            return ;
        }
        if(f[n].color!=0)
            down(n);
        if(mid>=r)
            update(l,r,n*2,x);
        else if(mid<l)
            update(l,r,n*2+1,x);
        else 
        {
            update(l,mid,n*2,x);
            update(mid+1,r,n*2+1,x);
        }
        up(&f[n],&f[n*2],&f[n*2+1]);
    }
    int query(int l,int r,int n,int x)
    {
        int mid=(f[n].l+f[n].r)/2;
        int a=0,b=0,ans=0;
        if(f[n].l==l&&f[n].r==r)
        {
            if(x==4)
                return f[n].one_max;
            else if(x==3)
                return f[n].sum;
        }
        if(f[n].color!=0)
            down(n);
        if(mid>=r)
            return query(l,r,n*2,x);
        else if(mid<l)
            return query(l,r,n*2+1,x);
        a=query(l,mid,n*2,x);
        b=query(mid+1,r,n*2+1,x);
        if(x==3)
            ans=a+b;
        else if(f[n*2].rnum==1&&f[n*2+1].lnum==1)
            ans=Max(a,b,min(mid-l+1,f[n*2].one_rmax)+min(r-mid,f[n*2+1].one_lmax));
        else 
            ans=max(a,b);
        return ans;
    }
    int main()
    {
        int i,k,n,m,t,l,r,x;
        while(scanf("%d",&t)>0)
        {
            while(t--)
            {
                scanf("%d%d",&n,&m);
                for(i=1;i<=n;i++)
                    scanf("%d",&date[i]);
                build(1,n,1);
                while(m--)
                {
                    scanf("%d%d%d",&x,&l,&r);
                    l++,r++;
                    if(x==0||x==1||x==2)
                    {
                        update(l,r,1,x);
                    }
                    else if(x==3||x==4)
                    {
                        k=query(l,r,1,x);
                        printf("%d\n",k);
                    }
                }
            }
        }
        return 0;
    }
     
  • 相关阅读:
    高级软件工程第四次作业(C++)
    248&258--高级软件工程第三次作业
    高级软件工程第二次作业--四则运算生成器
    2017282110258--高级软件工程--齐爽爽第一次作业
    一元多项式求导_9
    成绩排名_8
    写这个数 _7
    我要通过_6
    月饼_5
    Hadoop的读写类调用关系_图示
  • 原文地址:https://www.cnblogs.com/tom987690183/p/3059663.html
Copyright © 2011-2022 走看看