zoukankan      html  css  js  c++  java
  • poj2828 伸展树模拟

    用伸展树模拟插队比线段树快乐3倍。。

    但是pojT了。别的oj可以过,直接贴代码.

    每次更新时,找到第pos个人,splay到根,然后作为新root的左子树即可

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define maxn 200005
    using namespace std;
    
    int pre[maxn],ch[maxn][2],num[maxn],key[maxn],size[maxn],tot,root;
    void init(){
        tot=root=0;
        pre[root]=ch[root][1]=ch[root][0]=num[root]=key[root]=size[root]=0;
    }
    void newnode(int &r,int fa,int k,int val){
        r=++tot;
        ch[r][0]=ch[r][1]=0;
        num[r]=val;
        key[r]=k;
        pre[r]=fa;
        size[root]=1;
    }
    void pushup(int r){
        size[r]=size[ch[r][0]]+size[ch[r][1]]+1;
    }
    void rotate(int x,int kind){
        int fa=pre[x];
        ch[fa][!kind]=ch[x][kind];
        pre[ch[x][kind]]=fa;
        if(pre[fa])
            ch[pre[fa]][ch[pre[fa]][1]==fa]=x;
        pre[x]=pre[fa];
        pre[fa]=x;
        ch[x][kind]=fa;
        pushup(x);pushup(fa);
    }
    void splay(int r,int goal){
        while(pre[r]!=goal){
            if(pre[pre[r]]==goal) rotate(r,ch[pre[r]][0]==r);
            else {
                int fa=pre[r];
                int kind=ch[pre[fa]][0]==fa;//????????
                if(ch[fa][kind]==r){
                    rotate(r,!kind);
                    rotate(r,kind);
                }
                else {
                    rotate(fa,kind);
                    rotate(r,kind);
                }
            }
        }
        if(goal==0) root=r;
        pushup(r);pushup(root);
    }
    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],size[x],key[x]);
            Treavel(ch[x][1]);
        }
    }
    void debug()
    {
        printf("root:%d
    ",root);
        Treavel(root);
    }
    void Treval(int r){
        if(r){
            if(ch[r][0]) Treval(ch[r][0]);
            printf("%d ",num[r]);
            if(ch[r][1]) Treval(ch[r][1]);
        }
    }
    void getth(int pos){
        int r=root;
        while(size[ch[r][0]]+1!=pos){
            if(size[ch[r][0]]+1<pos)
                pos-=size[ch[r][0]]+1,r=ch[r][1];
            else r=ch[r][0];
        }
        splay(r,0);
    }
    void insert(int pos,int val){//?? 
        if(root==0) {
            newnode(root,0,pos,val);
            return;
        }
        else if(pos==0){
            int r=root;
            while(ch[r][0])
                r=ch[r][0];
            newnode(ch[r][0],r,pos,val);
            splay(ch[r][0],0);
            return;
        }
        else {
            getth(pos);
            int oldroot=root;
            newnode(root,0,pos,val);
            ch[root][1]=ch[oldroot][1];
            pre[ch[root][1]]=root;
            ch[oldroot][1]=0;
            pushup(oldroot);
            ch[root][0]=oldroot;
            pre[oldroot]=root;
            pushup(root);
        }
    }
    
    int main(){
        int n,pos,num;
        while(scanf("%d",&n)==1){
            init();
            for(int i=1;i<=n;i++){
                scanf("%d%d",&pos,&num);
                insert(pos,num);
                debug();
            }
            Treval(root);
            puts("");
        }
        return 0;
    } 
  • 相关阅读:
    简单的JAVAWeb选课系统
    公文流转系统001
    第九周动手动脑
    JAVA文件操作
    动手动脑-异常处理
    个人NABCD
    水王(课堂作业)
    软件学习进度表07
    软件工程学习进度表06
    软件工程个人作业05(二维数组求最大子数组的和)
  • 原文地址:https://www.cnblogs.com/zsben991126/p/9994309.html
Copyright © 2011-2022 走看看