• hdu 3397 Sequence operation


    Sequence operation

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


    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
     
    Author
    lxhgww&&shǎ崽
     
    Source
     
    Recommend
    lcy
    //写了这么多次的连续区间操作的、今天又是一早上
    //还好1Y了、比赛这种题果断要把自己的模板带上、、
    //不然要写疯掉、如果再出点小错啥的、、

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    #define lson l,m,k<<1
    #define rson m+1,r,k<<1|1
    #define N 100003
    using namespace std;
    struct node
    {
        int lm,rm,m;//lm代表从区间左端开始以1开始的最长连续序列,rm类同,m代表区间最长的连续1了
        int len,cover,sum;//sum就是成段更新的附带水货了
    };
    node st[N<<2];
    void up(int &k)
    {
        int ls=k<<1,rs=k<<1|1;
        st[k].sum=st[ls].sum+st[rs].sum;
        st[k].lm=st[ls].lm==st[ls].len?st[ls].len+st[rs].lm:st[ls].lm;
        st[k].rm=st[rs].rm==st[rs].len?st[rs].len+st[ls].rm:st[rs].rm;

        st[k].m=max(max(st[ls].m,st[rs].m),st[ls].rm+st[rs].lm);
        st[k].m=max(max(st[k].lm,st[k].rm),st[k].m);//经研究、发现这句可以不用
    }
    void qup(node &rt,node &ls,node &rs)
    {
        rt.lm=ls.lm==ls.len?ls.len+rs.lm:ls.lm;
        rt.rm=rs.rm==rs.len?rs.len+ls.rm:rs.rm;

        rt.m=max(max(ls.m,rs.m),ls.rm+rs.lm);
        rt.m=max(max(rt.lm,rt.rm),rt.m);//这里就类同了,可以不要这句、是多余的比较了
    }
    void down(int &k)
    {
    st[k<<1].cover=st[k<<1|1].cover=st[k].cover;
    st[k<<1].lm=st[k<<1].rm=st[k<<1].m=st[k<<1].sum=st[k].cover?st[k<<1].len:0;
    st[k<<1|1].lm=st[k<<1|1].rm=st[k<<1|1].m=st[k<<1|1].sum=st[k].cover?st[k<<1|1].len:0;
    st[k].cover=-1;
    }
    void build(int l,int r,int k)
    {
        st[k].len=r-l+1;
        if(l==r)
        {
            scanf("%d",&st[k].cover);
            st[k].lm=st[k].rm=st[k].m=st[k].sum=st[k].cover?1:0;
         return ;
        }
        st[k].cover=-1;
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        up(k);
    }
    bool flag;
    void update(int &L,int &R,int l,int r,int k)
    {  //printf("%d ",flag);
        if(L<=l&&R>=r)
        {
         st[k].lm=st[k].rm=st[k].m=st[k].sum=flag?st[k].len:0;
         st[k].cover=flag;
         return ;
        }
        if(st[k].cover!=-1)
          down(k);
        int m=(l+r)>>1;
        if(L<=m) update(L,R,lson);
        if(R>m)  update(L,R,rson);
        up(k);
    }
    void Xor(int &L,int &R,int l,int r,int k)
    {
        if(L<=l&&R>=r&&st[k].cover!=-1)
        {  // printf("k=%d %d %d\n",l,r,st[k].cover);
            st[k].cover^=1;
            st[k].lm=st[k].rm=st[k].m=st[k].sum=st[k].cover?st[k].len:0;
            return ;
        }
        if(st[k].cover!=-1)
           down(k);
        int m=(l+r)>>1;
        if(L<=m) Xor(L,R,lson);
        if(R>m)  Xor(L,R,rson);
        up(k);
    }
    int Qsum(int L,int R,int l,int r,int k)
    {
       if(L<=l&&R>=r)
       {
           return st[k].sum;
       }
       if(st[k].cover!=-1)
          down(k);
        int m=(l+r)>>1;
        int t1=0,t2=0;
        if(L<=m) t1=Qsum(L,R,lson);
        if(R>m)  t2=Qsum(L,R,rson);
        return t1+t2;
    }
    node Qconti(int &L,int &R,int l,int r,int k)
    {
       if(L<=l&&R>=r)
       {
           return st[k];
       }
       if(st[k].cover!=-1)
         down(k);
        int m=(l+r)>>1;
        node t1,t2;
        t1.len=t2.len=0;
        if(L<=m) t1=Qconti(L,R,lson);
        if(R>m)  t2=Qconti(L,R,rson);
        if(t1.len&&t2.len)
        {   node te;
            qup(te,t1,t2);
            te.len=t1.len+t2.len;
            return te;
        }
        if(t1.len)
           return t1;
        return t2;
    }
    int main()
    {
        int T;
        scanf("%d",&T);
        int n,m;
        int op,a,b;
        node t;
        while(T--)
        {
            scanf("%d%d",&n,&m);
            n--;
            build(0,n,1);
            while(m--)
            {
                scanf("%d%d%d",&op,&a,&b);
                switch(op)
                {
                    case 0:flag=0;update(a,b,0,n,1);break;
                    case 1:flag=1;update(a,b,0,n,1);break;
                    case 2:Xor(a,b,0,n,1);break;
                    case 3:printf("%d\n",Qsum(a,b,0,n,1));break;
                    case 4:t=Qconti(a,b,0,n,1);printf("%d\n",t.m);break;
                }
            }
        }
        return 0;
    }

  • 相关阅读:
    开心菜鸟系列学习笔记------javascript(5)
    开心菜鸟系列学习笔记-------javascript(3)
    开心菜鸟学习系列-----javascript(2)
    开心菜鸟学习系列笔记-----Javascript(1)
    开心菜鸟系列----函数作用域(javascript入门篇)
    开心菜鸟系列----变量的解读(javascript入门篇)
    开心菜鸟笔记系列---正则表达式笔记(入门篇)
    开心菜鸟笔记系列---博客开篇贴!(求支持)
    在开启bin-log日志下Mysql报错
    开心菜鸟学习系列学习笔记------------nodejs util公共函数
  • 原文地址:https://www.cnblogs.com/372465774y/p/2603517.html
Copyright © 2020-2023  润新知