码迷,mamicode.com
首页 > 其他好文 > 详细

poj2828 伸展树模拟

时间:2018-11-21 16:15:43      阅读:207      评论:0      收藏:0      [点我收藏+]

标签:splay   eva   scanf   ios   ace   ini   names   ==   ota   

用伸展树模拟插队比线段树快乐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 \n",x,ch[x][0],ch[x][1],pre[x],size[x],key[x]);
        Treavel(ch[x][1]);
    }
}
void debug()
{
    printf("root:%d\n",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;
} 

 

poj2828 伸展树模拟

标签:splay   eva   scanf   ios   ace   ini   names   ==   ota   

原文地址:https://www.cnblogs.com/zsben991126/p/9994309.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!