1. 程式人生 > >poj2828 伸展樹模擬

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 \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; }