zoukankan      html  css  js  c++  java
  • hdu3487 伸展树(区间搬移 区间旋转)

        对于区间旋转使用lazy思想就能解决。然后对于区间搬移,先把a-1结点做根,b+1作为它的右孩子,这样ch[ch[root][1]][0]就是区间[a,b],现将他取出。

    然后在将当前的树伸展,把c结点转到根,c+1作为它的右孩子,这样c+1结点的左孩子就是空的,直接将上次取出的作为c+1结点的做孩子即可。

    #include<queue>
    #include<stack>
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define INF 99999999
    #define ll __int64
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define key_value ch[ch[root][1]][0]
    using namespace std;
    const int MAXN = 3*100010;
    int pre[MAXN],ch[MAXN][2],siz[MAXN],key[MAXN],rev[MAXN],root,tot1;
    int n;
    void Treavel(int x)
    {
        if(x)
        {
            Treavel(ch[x][0]);
            printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size=%2d key=%2d
    ",x,ch[x][0],ch[x][1],pre[x],siz[x],key[x]);
            Treavel(ch[x][1]);
        }
    }
    void debug()
    {
        printf("root:%d
    ",root);
        Treavel(root);
    }
    void Newnode(int &rt,int pa,int k)
    {
        rt = ++tot1;
        pre[rt] = pa;
        siz[rt] = 1;
        rev[rt] = 0;
        key[rt] = k;
        ch[rt][0] = ch[rt][1] = 0;
    }
    void pushup(int rt)
    {
        siz[rt] = siz[ch[rt][0]] + siz[ch[rt][1]] + 1;
    }
    void pushdown(int rt)
    {
        if(rev[rt]){
            rev[ch[rt][0]] ^= 1;
            rev[ch[rt][1]] ^= 1;
            swap(ch[rt][0],ch[rt][1]);
            rev[rt] = 0;
        }
    }
    void build(int &rt,int l,int r,int pa)
    {
        if(l > r)
            return ;
        int m = (l+r)/2;
        Newnode(rt,pa,m);
        build(ch[rt][0],l,m-1,rt);
        build(ch[rt][1],m+1,r,rt);
        pushup(rt);
    }
    void Init()
    {
        tot1 = root = 0;
        pre[root] = siz[root] = key[root] = rev[root] = 0;
        ch[root][0] = ch[root][1] = 0;
        Newnode(root,0,-1);
        Newnode(ch[root][1],root,-1);
        build(key_value,1,n,ch[root][1]);
        pushup(ch[root][1]);
        pushup(root);
    }
    void Rotate(int rt,int kind)
    {
        int y = pre[rt];
        pushdown(y);
        pushdown(rt);
        ch[y][!kind] = ch[rt][kind];
        pre[ch[rt][kind]] = y;
        if(pre[y]){
            ch[pre[y]][ch[pre[y]][1]==y] = rt;
        }
        pre[rt] = pre[y];
        ch[rt][kind] = y;
        pre[y] = rt;
        pushup(y);
    }
    void splay(int rt,int goal)
    {
        pushdown(rt);
        while(pre[rt] != goal)
        {
            if(pre[pre[rt]] == goal){
                pushdown(pre[rt]);
                pushdown(rt);
                Rotate(rt,ch[pre[rt]][0]==rt);
            }
            else {
                pushdown(pre[pre[rt]]);
                pushdown(pre[rt]);
                pushdown(rt);
                int y = pre[rt];
                int kind = ch[pre[y]][0]==y;
                if(ch[y][kind] == rt){
                    Rotate(rt,!kind);
                    Rotate(rt,kind);
                }
                else {
                    Rotate(y,kind);
                    Rotate(rt,kind);
                }
            }
        }
        if(goal == 0)
            root = rt;
        pushup(rt);
    }
    int Get_kth(int rt,int k)
    {
        pushdown(rt);
        int t = siz[ch[rt][0]] + 1;
        if(t == k)
            return rt;
        else if(t > k){
            return Get_kth(ch[rt][0],k);
        }
        else {
            return Get_kth(ch[rt][1],k-t);
        }
        pushup(rt);
    }
    void cut(int x,int y,int z)
    {
        splay(Get_kth(root,x),0);
        splay(Get_kth(root,y+2),root);
        //debug();
        int tmp = key_value;
        key_value = 0;
        pushup(ch[root][1]);
        pushup(root);
        splay(Get_kth(root,z+1),0);
        splay(Get_kth(root,z+2),root);
        //debug();
        key_value = tmp;
        pre[tmp] = ch[root][1];
        pushup(ch[root][1]);
        pushup(root);
        //debug();
    }
    int flag;
    void display(int rt)
    {
        if(rt == 0)
            return ;
        pushdown(rt);
        display(ch[rt][0]);
        if(!flag && rt !=1 && rt != 2){
            flag = 1;
            printf("%d",key[rt]);
        }
        else if(rt !=1 && rt != 2){
            printf(" %d",key[rt]);
        }
        display(ch[rt][1]);
    }
    int main()
    {
        int i,j,m;
        while(~scanf("%d%d",&n,&m),n!=-1&&m!=-1)
        {
            Init();
            char work[10];
            while(m--)
            {
                scanf("%s",work);
                if(work[0] == 'F'){
                    int x,y;
                    scanf("%d%d",&x,&y);
                    splay(Get_kth(root,x),0);
                    splay(Get_kth(root,y+2),root);
                    rev[key_value] ^= 1;
                    //debug();
                }
                else {
                    int x,y,z;
                    scanf("%d%d%d",&x,&y,&z);
                    cut(x,y,z);
                }
            }
            //debug();
            flag = 0;
            display(root);
            cout<<endl;
        }
    }
  • 相关阅读:
    三个心态做人做学问 沧海
    成功走职场要找准自己的"快捷键" 沧海
    免费离线下载 拂晓风起
    Hibernate 获取某个表全部记录时 奇怪现象 (重复出现某个记录) 拂晓风起
    无法读取mdb 如果连接不了ACCESS mdb文件,就尝试安装MDAC 拂晓风起
    Netbeans 使用 Hibernate 逆向工程 生成hbm和pojo 拂晓风起
    如何点击单选框 radio 后面的文字,选中单选框 拂晓风起
    Java 连接access 使用access文件 不用配置 拂晓风起
    mysql下如何执行sql脚本 拂晓风起
    Hibernate配置access Hibernate 连接 access 拂晓风起
  • 原文地址:https://www.cnblogs.com/sweat123/p/5141435.html
Copyright © 2011-2022 走看看