• (简单) HDU 3397 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]
     
      典型的水题,对一段01序列进行区间覆盖和反转,维护1的个数,连续1的个数,前缀1的个数,后缀1的个数,以及连续0,前缀0,后缀0,用来计算反转时的1.
      不过还是写错了个地方,在程序里面标记出来了。
     
    代码如下:
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    #define lc po*2
    #define rc po*2+1
    #define lson L,M,lc
    #define rson M+1,R,rc
    
    using namespace std;
    
    const int maxn=1e5+5;
    
    int sum[maxn*4],lsum[2][maxn*4],rsum[2][maxn*4],msum[2][maxn*4];
    int COL[maxn*4],XOR[maxn*4];
    
    inline void swap(int &a,int &b)
    {
        int temp=a;
        a=b;
        b=temp;
    }
    
    void pushUP(int po,int len)
    {
        sum[po]=sum[lc]+sum[rc];
        
        for(int i=0;i<2;++i)
        {
            msum[i][po]=max(msum[i][lc],msum[i][rc]);
            msum[i][po]=max(msum[i][po],lsum[i][rc]+rsum[i][lc]);
        
            lsum[i][po]=lsum[i][lc];
            if(lsum[i][lc]==(len-(len/2)))
                lsum[i][po]+=lsum[i][rc];
        
            rsum[i][po]=rsum[i][rc];
            if(rsum[i][rc]==(len/2))
                rsum[i][po]+=rsum[i][lc];
        }
    }
    
    void pushDown(int po,int len)
    {
        if(COL[po]!=-1)
        {
            COL[lc]=COL[rc]=COL[po];
            XOR[lc]=XOR[rc]=0;
    
            sum[lc]=COL[po]*(len-(len/2));
            sum[rc]=COL[po]*(len/2);
    
            for(int i=0;i<2;++i)
            {
                msum[i][lc]=lsum[i][lc]=rsum[i][lc]=(i ? sum[lc] : len-(len/2)-sum[lc]);
                msum[i][rc]=rsum[i][rc]=lsum[i][rc]=(i ? sum[rc] : (len/2)-sum[rc]);
            }
    
            COL[po]=-1;
        }
    
        if(XOR[po])
        {
            XOR[lc]=!XOR[lc];
            XOR[rc]=!XOR[rc];
    
            sum[lc]=len-(len/2)-sum[lc];
            sum[rc]=(len/2)-sum[rc];
    
            swap(msum[0][lc],msum[1][lc]);
            swap(msum[0][rc],msum[1][rc]);
    
            swap(lsum[0][lc],lsum[1][lc]);
            swap(rsum[0][lc],rsum[1][lc]);
    
            swap(lsum[0][rc],lsum[1][rc]);
            swap(rsum[0][rc],rsum[1][rc]);
    
            XOR[po]=0;
        }
    }
    
    void build_tree(int L,int R,int po)
    {
        COL[po]=-1;
        XOR[po]=0;
    
        if(L==R)
        {
            int temp;
            scanf("%d",&temp);
    
            sum[po]=temp;
            lsum[0][po]=rsum[0][po]=msum[0][po]=1-temp;
            lsum[1][po]=rsum[1][po]=msum[1][po]=temp;
    
            return;
        }
    
        int M=(L+R)/2;
    
        build_tree(lson);
        build_tree(rson);
    
        pushUP(po,R-L+1);
    }
    
    void update_col(int ul,int ur,int ut,int L,int R,int po)
    {
        if(ul<=L&&ur>=R)
        {
            COL[po]=ut;
            XOR[po]=0;
    
            sum[po]=ut*(R-L+1);
            lsum[1][po]=rsum[1][po]=msum[1][po]=sum[po];
            lsum[0][po]=rsum[0][po]=msum[0][po]=R-L+1-sum[po];
    
            return;
        }
    
        pushDown(po,R-L+1);
    
        int M=(L+R)/2;
    
        if(ul<=M)
            update_col(ul,ur,ut,lson);
        if(ur>M)
            update_col(ul,ur,ut,rson);
    
        pushUP(po,R-L+1);
    }
    
    void update_xor(int ul,int ur,int L,int R,int po)
    {
        if(ul<=L&&ur>=R)
        {
            XOR[po]=!XOR[po];
    
            sum[po]=R-L+1-sum[po];
            swap(msum[0][po],msum[1][po]);
            swap(lsum[0][po],lsum[1][po]);
            swap(rsum[0][po],rsum[1][po]);
    
            return;
        }
    
        pushDown(po,R-L+1);
    
        int M=(L+R)/2;
    
        if(ul<=M)
            update_xor(ul,ur,lson);
        if(ur>M)
            update_xor(ul,ur,rson);
    
        pushUP(po,R-L+1);
    }
    
    int query_sum(int ql,int qr,int L,int R,int po)
    {
        if(ql<=L&&qr>=R)
            return sum[po];
    
        pushDown(po,R-L+1);
    
        int M=(L+R)/2;
    
        if(qr<=M)
            return query_sum(ql,qr,lson);
        if(ql>M)
            return query_sum(ql,qr,rson);
    
        return query_sum(ql,qr,lson)+query_sum(ql,qr,rson);
    }
    
    int query_max(int ql,int qr,int L,int R,int po)
    {
        if(ql<=L&&qr>=R)
            return msum[1][po];
    
        pushDown(po,R-L+1);
    
        int M=(L+R)/2;
        int ans=0;
    
        if(qr<=M)
            return query_max(ql,qr,lson);
        if(ql>M)
            return query_max(ql,qr,rson);
    
        ans=max(query_max(ql,qr,lson),query_max(ql,qr,rson));
        ans=max(ans,min(rsum[1][lc],M-ql+1)+min(lsum[1][rc],qr-M));            //!!!
    
        return ans;
    }
    
    int main()
    {
        int T;
        int N,M;
        int a,b,c;
        cin>>T;
    
        while(T--)
        {
            scanf("%d %d",&N,&M);
    
            build_tree(0,N-1,1);
    
            while(M--)
            {
                scanf("%d %d %d",&a,&b,&c);
    
                switch(a)
                {
                    case 0:
                        update_col(b,c,0,0,N-1,1);
                        break;
                    case 1:
                        update_col(b,c,1,0,N-1,1);
                        break;
                    case 2:
                        update_xor(b,c,0,N-1,1);
                        break;
                    case 3:
                        printf("%d
    ",query_sum(b,c,0,N-1,1));
                        break;
                    case 4:
                        printf("%d
    ",query_max(b,c,0,N-1,1));
                        break;
                }
            }
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    Quick Sort 快速排序的原理及实现
    IAR_FOR_STM8开发之DEMO的建立
    跨域或者Internet访问Remoting[Remoting FAQ]
    2020 7 22 每日总结
    2020 7 23 每日总结
    2020 7 27 每日总结
    2020 7 20 每日总结
    2020 7 29 每日总结
    2020 7 21 每日总结
    2020 7 28 每日总结
  • 原文地址:https://www.cnblogs.com/whywhy/p/4210658.html
Copyright © 2020-2023  润新知