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 (线段树 插队问题)