• hdu3397 Sequence operation


    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.
     

    Output
    For each output operation , output the result.
     

    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

    这道题是前面线段树知识的综合题,也和之前有些不同,是个很好的训练题,做了很长时间啊,还需努力。这里的难点是异或运算,即把区间中的0变成1,1变成0.这里我维护每个区间的llen0,rlen0,tlen0,llen1,rlen1,tlen1,即区间从左端点起的向右最大连续0(1)区间长度,从右端起的最大向左连续0(1)区间长度,以及区间最大的连续0(1)区间长度,然后异或操作的时候,只要把0,1换一下,然后用pushup操作就可以了,再记录一个异或操作符x_or.

    <pre name="code" class="cpp">#include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<string>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    #define inf 0x7fffffff
    #define maxn 100050
    int a[maxn];
    struct node{
        int l,r,yihuo,cnt;
        int llen0,rlen0,tlen0;
        int llen1,rlen1,tlen1;
        int num0,num1;
    }b[4*maxn];
    
    int num1,num2;
    
    void pushdown(int i)
    {
        if(b[i].l==b[i].r)return;
        if(b[i].cnt!=-1){
            b[i*2].cnt=b[i*2+1].cnt=b[i].cnt;
            b[i*2].yihuo=b[i*2+1].yihuo=0;
            if(b[i].cnt==0){
                b[i*2].llen0=b[i*2].rlen0=b[i*2].tlen0=b[i*2].r-b[i*2].l+1;
                b[i*2].llen1=b[i*2].rlen1=b[i*2].tlen1=0;
                b[i*2].num0=b[i*2].r-b[i*2].l+1;
                b[i*2].num1=0;
    
                b[i*2+1].llen0=b[i*2+1].rlen0=b[i*2+1].tlen0=b[i*2+1].r-b[i*2+1].l+1;
                b[i*2+1].llen1=b[i*2+1].rlen1=b[i*2+1].tlen1=0;
                b[i*2+1].num0=b[i*2+1].r-b[i*2+1].l+1;
                b[i*2+1].num1=0;
    
    
            }
            else if(b[i].cnt==1){
                b[i*2].llen0=b[i*2].rlen0=b[i*2].tlen0=0;
                b[i*2].llen1=b[i*2].rlen1=b[i*2].tlen1=b[i*2].r-b[i*2].l+1;
                b[i*2].num0=0;
                b[i*2].num1=b[i*2].r-b[i*2].l+1;
    
                b[i*2+1].llen0=b[i*2+1].rlen0=b[i*2+1].tlen0=0;
                b[i*2+1].llen1=b[i*2+1].rlen1=b[i*2+1].tlen1=b[i*2+1].r-b[i*2+1].l+1;
                b[i*2+1].num0=0;
                b[i*2+1].num1=b[i*2+1].r-b[i*2+1].l+1;
    
    
            }
            b[i].cnt=-1;
        }
    
        if(b[i].yihuo!=0){
            b[i*2].yihuo=1^b[i*2].yihuo;
            swap(b[i*2].llen0,b[i*2].llen1);
            swap(b[i*2].rlen0,b[i*2].rlen1);
            swap(b[i*2].tlen0,b[i*2].tlen1);
            swap(b[i*2].num0,b[i*2].num1);
    
            /*
            if(b[i*2].cnt!=-1){  这里和下面注释的不能写,因为如果换了的话就和父亲节点的信息不同了
                b[i*2].cnt^=1;
            }
            */
    
    
    
            b[i*2+1].yihuo=1^b[i*2+1].yihuo;
            swap(b[i*2+1].llen0,b[i*2+1].llen1);
            swap(b[i*2+1].rlen0,b[i*2+1].rlen1);
            swap(b[i*2+1].tlen0,b[i*2+1].tlen1);
            swap(b[i*2+1].num0,b[i*2+1].num1);
    
            /*
            if(b[i*2+1].cnt!=-1){
                b[i*2+1].cnt^=1;
            }
            */
    
            b[i].yihuo=0;
        }
    }
    
    
    void pushup(int i)
    {
        if(b[i].l==b[i].r)return;
        b[i].num0=b[i*2].num0+b[i*2+1].num0;
        b[i].num1=b[i*2].num1+b[i*2+1].num1;
        b[i].llen0=b[i*2].llen0;
        b[i].rlen0=b[i*2+1].rlen0;
        if(b[i*2].llen0==b[i*2].r-b[i*2].l+1){
            b[i].llen0+=b[i*2+1].llen0;
        }
        if(b[i*2+1].rlen0==b[i*2+1].r-b[i*2+1].l+1){
            b[i].rlen0+=b[i*2].rlen0;
        }
        b[i].tlen0=max(b[i*2].tlen0,b[i*2+1].tlen0);
        b[i].tlen0=max(b[i*2].rlen0+b[i*2+1].llen0,b[i].tlen0);
    
    
    
        b[i].llen1=b[i*2].llen1;
        b[i].rlen1=b[i*2+1].rlen1;
        if(b[i*2].llen1==b[i*2].r-b[i*2].l+1){
            b[i].llen1+=b[i*2+1].llen1;
        }
        if(b[i*2+1].rlen1==b[i*2+1].r-b[i*2+1].l+1){
            b[i].rlen1+=b[i*2].rlen1;
        }
        b[i].tlen1=max(b[i*2].tlen1,b[i*2+1].tlen1);
        b[i].tlen1=max(b[i*2].rlen1+b[i*2+1].llen1,b[i].tlen1);
    
    
    
    }
    
    
    void build(int l,int r,int i)
    {
        int mid;
        b[i].l=l;b[i].r=r;b[i].yihuo=0;b[i].cnt=-1;
        if(l==r){
            if(a[l]==0){
                b[i].llen0=b[i].rlen0=b[i].tlen0=1;
                b[i].llen1=b[i].rlen1=b[i].tlen1=0;
                b[i].num0=1;
                b[i].num1=0;
            }
            else{
                b[i].llen0=b[i].rlen0=b[i].tlen0=0;
                b[i].llen1=b[i].rlen1=b[i].tlen1=1;
                b[i].num0=0;
                b[i].num1=1;
            }
            return;
        }
        mid=(l+r)/2;
        build(l,mid,i*2);
        build(mid+1,r,i*2+1);
        pushup(i);
    }
    
    
    void update01(int l,int r,int num,int i)
    {
        int mid;
        if(b[i].l==l && b[i].r==r){
            b[i].yihuo=0;
            b[i].cnt=num;
            if(num==0){
                b[i].llen0=b[i].rlen0=b[i].tlen0=b[i].r-b[i].l+1;
                b[i].llen1=b[i].rlen1=b[i].tlen1=0;
                b[i].num0=b[i].r-b[i].l+1;
                b[i].num1=0;
            }
            else{
                b[i].llen0=b[i].rlen0=b[i].tlen0=0;
                b[i].llen1=b[i].rlen1=b[i].tlen1=b[i].r-b[i].l+1;
                b[i].num0=0;
                b[i].num1=b[i].r-b[i].l+1;
            }
            return;
        }
        pushdown(i);
        mid=(b[i].l+b[i].r)/2;
        if(r<=mid)update01(l,r,num,i*2);
        else if(l>mid)update01(l,r,num,i*2+1);
        else{
            update01(l,mid,num,i*2);
            update01(mid+1,r,num,i*2+1);
        }
        pushup(i);
    
    }
    
    void update2(int l,int r,int i)
    {
        int mid;
        if(b[i].l==l && b[i].r==r){
            b[i].yihuo=1^b[i].yihuo;
            swap(b[i].llen0,b[i].llen1);
            swap(b[i].rlen0,b[i].rlen1);
            swap(b[i].tlen0,b[i].tlen1);
            swap(b[i].num0,b[i].num1);
            //if(b[i].cnt!=-1)b[i].cnt^=1;这句不用写
            return;
        }
        pushdown(i);//pushdown(i)放上面下面都行的
        mid=(b[i].l+b[i].r)/2;
        if(r<=mid)update2(l,r,i*2);
        else if(l>mid)update2(l,r,i*2+1);
        else{
            update2(l,mid,i*2);
            update2(mid+1,r,i*2+1);
        }
        pushup(i);
    }
    
    void question1(int l,int r,int i)
    {
        int mid;
        if(b[i].l==l && b[i].r==r){
            num1+=b[i].num1;
            return;
        }
        pushdown(i);
        mid=(b[i].l+b[i].r)/2;
        if(r<=mid)question1(l,r,i*2);
        else if(l>mid)question1(l,r,i*2+1);
        else{
            question1(l,mid,i*2);
            question1(mid+1,r,i*2+1);
        }
    
    
    }
    int question2(int l,int r,int i)
    {
        int mid;
        if(b[i].l==l && b[i].r==r){
            return b[i].tlen1;
        }
        pushdown(i);
        mid=(b[i].l+b[i].r)/2;
        if(r<=mid){
            return question2(l,r,i*2);
        }
        else if(l>mid){
            return question2(l,r,i*2+1);
        }
        else{
            int l1,r1;
            l1=max(b[i*2].r-b[i*2].rlen1+1,l);
            r1=min(b[i*2+1].l+b[i*2+1].llen1-1,r);
            int temp=r1-l1+1;
            temp=max(temp,question2(l,mid,i*2) );
            temp=max(temp,question2(mid+1,r,i*2+1));
            return temp;
        }
    }
    
    
    
    
    
    int main()
    {
        int n,m,i,j,T,f,c,d;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(i=1;i<=n;i++){
                scanf("%d",&a[i]);
            }
            build(1,n,1);
            for(i=1;i<=m;i++){
                scanf("%d%d%d",&f,&c,&d);
                c++;d++;
                if(f==0){
                    update01(c,d,0,1);
                }
                if(f==1){
                    update01(c,d,1,1);
                }
                else if(f==2){
                    update2(c,d,1);
                }
                else if(f==3){
                    num1=0;
                    question1(c,d,1);
                    printf("%d
    ",num1);
                }
                else if(f==4){
                    printf("%d
    ",question2(c,d,1));
                }
            }
        }
        return 0;
    }



    
    
  • 相关阅读:
    PHP fread() 函数
    PHP fputs() 函数
    PHP fputcsv() 函数
    PHP fpassthru() 函数
    分区表基本类型
    C# const 和 readonly 有什么区别
    win2d 画出好看的图形
    win2d 画出好看的图形
    win2d 渐变颜色
    win2d 渐变颜色
  • 原文地址:https://www.cnblogs.com/herumw/p/9464781.html
Copyright © 2020-2023  润新知