poj2828 伸展树模拟

Posted zsben991126

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;
} 

 

以上是关于poj2828 伸展树模拟的主要内容,如果未能解决你的问题,请参考以下文章

poj2828 Buy Tickets (线段树 插队问题)

POJ - 2828 Buy Tickets(线段树单点更新)

POJ 2828 Buy Tickets(线段树单点)

poj2828-Buy Tickets

POJ 2828Buy Tickets(线段树的单点维护)

POJ-2828 Buy Tickets---线段树+逆序