HDU3397 Sequence operation(線段樹)

來源:互聯網
上載者:User

點擊開啟題目連結,還有一個類似的題,只進行01翻轉操作和最大連續查詢,HDU3911
Black And White

對一個數列進行如下操作:

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]

區間屬性

1.最大連續長度=Max(左區間最大,有區間最大,左區間右起最大+有區間左起最大)

2.左端點開始的最大連續長度=左區間最大左連續  或   左區間長度+右區間最大左連續(如果左區間最大左連續==左區間長度)

3.有端點開始的最大連續長度,同上;

注意:

 1. 所有翻轉的flag都要用 ^操作,避免連續翻轉兩次而未更新的區間。

 2.全置的優先順序高於翻轉


import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.StreamTokenizer;public class Main{    class SegTree{        class node{            int left,right;            int flag,num0,num1;            int max0,l0,r0;            int max1,l1,r1;                        int mid(){                return (left+right)>>1;            }                 int length(){                return right-left+1;            }            void init(int k){                if(k==0){                    num0=max0=l0=r0=length();                    num1=l1=r1=max1=0;                }                else                {                    max1=l1=r1=num1=length();                    num0=max0=l0=r0=0;                }            }        }                node tree[];        SegTree(int maxn){            tree=new node[maxn*5];        }        void init(int left,int right,int idx,int[]a){            tree[idx]=new node();            tree[idx].left=left;            tree[idx].right=right;            tree[idx].flag=-1;            if(left==right){            tree[idx].init(a[left]);            return;            }            int mid=tree[idx].mid();            init(left,mid,idx<<1,a);            init(mid+1,right,(idx<<1)|1,a);            pushup(idx);        }        void update(int left,int right,int idx,int op){            pushdown(idx);            if(tree[idx].left>=left&&tree[idx].right<=right){                if(op==2)                    reverse(idx);                else                    tree[idx].flag=op;                return;            }            int mid=tree[idx].mid();            if(left<=mid)                update(left,right,idx<<1,op);            if(right>mid)                update(left,right,(idx<<1)|1,op);            pushup(idx);        }        int query(int left,int right,int idx,int type)        {               pushdown(idx);            if(tree[idx].left==left&&tree[idx].right==right){                if(type==3)                    return tree[idx].num1;                else                    return tree[idx].max1;            }            int mid=tree[idx].mid();            if(right<=mid)                return query(left,right,idx<<1,type);            else if(left>mid)                return query(left,right,(idx<<1)|1,type);            else{                int a=query(left,mid,idx<<1,type);                int b=query(mid+1,right,(idx<<1)|1,type);                if(type==3)                    return a+b;                int c = Math.min(tree[idx << 1].r1, mid - left + 1)                + Math.min(tree[(idx << 1) | 1].l1, right - mid);                return Math.max(Math.max(a,b),c);            }                        }        void pushup(int idx){            if(tree[idx].left==tree[idx].right)                return;            pushdown(idx<<1);            pushdown((idx<<1)|1);            tree[idx].num1=tree[idx<<1].num1+tree[(idx<<1)|1].num1;            tree[idx].num0=tree[idx<<1].num0+tree[(idx<<1)|1].num0;            int a=tree[idx<<1].max0;            int b=tree[(idx<<1)|1].max0;            int c=tree[idx<<1].r0+tree[(idx<<1)|1].l0;            tree[idx].max0=Math.max(Math.max(a,b), c);                                    tree[idx].l0=tree[idx<<1].l0;            if(tree[idx].l0==tree[idx<<1].length())                tree[idx].l0+=tree[(idx<<1)|1].l0;            tree[idx].r0=tree[(idx<<1)|1].r0;            if(tree[(idx<<1)|1].r0==tree[(idx<<1)|1].length())                tree[idx].r0+=tree[idx<<1].r0;                         a=tree[idx<<1].max1;             b=tree[(idx<<1)|1].max1;             c=tree[idx<<1].r1+tree[(idx<<1)|1].l1;            tree[idx].max1=Math.max(Math.max(a,b), c);                                    tree[idx].l1=tree[idx<<1].l1;            if(tree[idx].l1==tree[idx<<1].length())                tree[idx].l1+=tree[(idx<<1)+1].l1;            tree[idx].r1=tree[(idx<<1)|1].r1;            if(tree[(idx<<1)|1].r1==tree[(idx<<1)|1].length())                tree[idx].r1+=tree[idx<<1].r1;                    }        void pushdown(int idx){            if(tree[idx].flag==2){                int t=tree[idx].l0;                tree[idx].l0=tree[idx].l1;                tree[idx].l1=t;                t=tree[idx].r0;                tree[idx].r0=tree[idx].r1;                tree[idx].r1=t;                t=tree[idx].max0;                tree[idx].max0=tree[idx].max1;                tree[idx].max1=t;                tree[idx].flag=-1;                t=tree[idx].num0;                tree[idx].num0=tree[idx].num1;                tree[idx].num1=t;                if(tree[idx].left!=tree[idx].right){                    t=idx<<1;                    reverse(t);                    t++;                    reverse(t);                }            }            if(tree[idx].flag==1||tree[idx].flag==0){                int t=tree[idx].flag;                tree[idx].init(t);                tree[idx].flag=-1;                if(tree[idx].left!=tree[idx].right){                    tree[idx<<1].flag=t;                    tree[(idx<<1)|1].flag=t;                }            }        }        void reverse(int idx){            if(tree[idx].flag==2)                tree[idx].flag=-1;                else if(tree[idx].flag==-1)                    tree[idx].flag=2;                else                    tree[idx].flag^=1;        }    }    StreamTokenizer in = new StreamTokenizer(new BufferedReader(            new InputStreamReader(System.in)));    final int next() throws IOException {        in.nextToken();        return (int) in.nval;    }    SegTree st=new SegTree(100010);    int a[]=new int[100010];   void run() throws IOException{       int t=next();       while(t-->0){           int n=next();           int m=next();           for(int i=1;i<=n;i++)               a[i]=next();           st.init(1, n, 1, a);           while(m-->0){               int k=next();               int a=next()+1;               int b=next()+1;               if(k<3)                   st.update(a, b, 1, k);               else                   System.out.println(st.query(a, b, 1, k));           }       }   }    public static void main(String[] args) throws IOException {        new Main().run();    }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.