hdu 3487 區間 翻轉 切割 插入 splay

來源:互聯網
上載者:User

http://acm.hdu.edu.cn/showproblem.php?pid=3487

提取一段區間,插入到另一個位置,只要寫好了關鍵的三個函數就很輕鬆了

/*區間翻轉,注意標記的下傳*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define L ch[x][0]#define R ch[x][1]#define KT (ch[ ch[rt][1] ][0])const int maxn = 300010;struct SplayTree {    int sz[maxn];    int ch[maxn][2];    int pre[maxn];    int rt,top;    inline void down(int x){        if(flip[x]) {            flip[ L ] ^= 1;            flip[ R ] ^= 1;            swap(L,R);            flip[x]=0;        }    }    inline void up(int x){        sz[x]=1+sz[ L ] + sz[ R ];    }    inline void Rotate(int x,int f){        int y=pre[x];        down(y);        down(x);        ch[y][!f] = ch[x][f];        pre[ ch[x][f] ] = y;        pre[x] = pre[y];        if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x;        ch[x][f] = y;        pre[y] = x;        up(y);    }    inline void Splay(int x,int goal){//將x旋轉到goal的下面        down(x);//防止pre[x]就是目標點,下面的迴圈就進不去了,x的資訊就傳不下去了        while(pre[x] != goal){            down(pre[pre[x]]); down(pre[x]);down(x);//在旋轉之前需要先下傳標記,因為節點的位置可能會發生改變            if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x);            else   {                int y=pre[x],z=pre[y];                int f = (ch[z][0]==y);                if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f);                else Rotate(y,f),Rotate(x,f);            }        }        up(x);        if(goal==0) rt=x;    }    inline void RTO(int k,int goal){//將第k位元旋轉到goal的下面        int x=rt;        down(x);        while(sz[ L ]+1 != k) {            if(k < sz[ L ] + 1 ) x=L;            else {                k-=(sz[ L ]+1);                x = R;            }            down(x);        }        Splay(x,goal);    }    void vist(int x){        if(x){            printf("結點%2d : 左兒子  %2d   右兒子  %2d   %2d  flip:%d\n",x,L,R,val[x],flip[x]);            vist(L);            vist(R);        }    }    void Newnode(int &x,int c,int f){        x=++top;           L = R = 0; pre[x]=f;        sz[x]=1; val[x]=c;  flip[x]=0;    }    inline void build(int &x,int l,int r,int f){        if(l>r) return ;        int m=l+r>>1;        Newnode(x,m,f);        build(L , l , m-1 , x);        build(R , m+1 , r , x);        pre[x]=f;        up(x);    }    inline void init(int n){        ch[0][0]=ch[0][1]=pre[0]=sz[0]=0;        rt=top=0; flip[0]=0; val[0]=0;        Newnode(rt,-1,0);Newnode(ch[rt][1],-1,rt);sz[rt]=2;        build(KT,1,n,ch[rt][1]);    //    vist(rt);    }    void print(int x) {if(x) {down(x);print(L);if(val[x]!=-1) {if(flag) printf(" ");printf("%d",val[x]);flag=1;}print(R);}}    void OUT() {flag=0;print(rt);printf("\n");}void gao1(int l,int r,int c) {RTO(l-1+1,0);RTO(r+1+1,rt);int tmp=KT;KT=0;up(ch[rt][1]);up(rt);RTO(c+1,0);RTO(c+1+1,rt);KT=tmp;pre[tmp]=ch[rt][1];up(ch[rt][1]);up(rt);}void gao2(int l,int r) {RTO(l-1+1,0);RTO(r+1+1,rt);flip[KT] ^= 1;}    int flag;    int flip[maxn];    int val[maxn];}spt;int main(){char op[10];    int n,m,a,b,c;    while(scanf("%d%d",&n,&m)!=EOF){if(n==-1 && m==-1) break;        spt.init(n);        for(int i=1;i<=m;i++) {scanf("%s",op);if(op[0]=='C') {scanf("%d%d%d",&a,&b,&c);spt.gao1(a,b,c);} else {scanf("%d%d",&a,&b);spt.gao2(a,b);}}spt.OUT();    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.