POJ 3481Double Queue Splay
#include<stdio.h> #include<string.h> const int N=1e6+11; int t[N][2],data[N],id[N],fa[N],size,root; void Rotate(int x,int w){//0:左旋 1:右旋 int y=fa[x]; t[y][!w]=t[x][w]; if(t[x][w]) fa[t[x][w]]=y; fa[x]=fa[y]; if(fa[y]) t[fa[y]][t[fa[y]][1]==y]=x; t[x][w]=y; fa[y]=x; } void Splay(int x,int y){ while(fa[x]!=y){ if(t[fa[x]][0]==x) Rotate(x,1); else Rotate(x,0); } if(y==0) root=x; } void newnode(int &rt,int father,int v,int Id){ rt=++size; t[rt][0]=t[rt][1]=0; fa[rt]=father; data[rt]=v; id[rt]=Id; } void Insert(int v,int Id){ int x=root; for(;t[x][v>data[x]];x=t[x][v>data[x]]); newnode(t[x][v>data[x]],x,v,Id); Splay(t[x][v>data[x]],0); } void init(){ size=root=0;//root初始化为0,插入第一个点后root会被更新 t[0][0]=t[0][1]=0; } void Delete(int x){ if(x==root){ if(!t[x][0]&&!t[x][1]) init(); else{ int p=t[x][1]?1:0; fa[t[x][p]]=0; root=t[x][p]; } }else{//因为删除的点要么没有前驱,要么没有后继,所以可以直接删除,这里也是不超时的主要原因 int y=fa[x]; int p=(t[y][1]==x); t[y][p]=t[x][!p]; fa[t[x][!p]]=y; Splay(y,0); } } void low(){ int x=root; if(x){ for(;t[x][0];x=t[x][0]); printf("%d\n",id[x]); Delete(x); } else{ puts("0"); } } void high(){ int x=root; if(x){ for(;t[x][1];x=t[x][1]); printf("%d\n",id[x]); Delete(x); } else{ puts("0"); } } int main(){ int op; init(); while(scanf("%d",&op)!=EOF&&op){ if(op==1){ int Id,p; scanf("%d%d",&Id,&p); Insert(p,Id); } else if(op==2) high(); else low(); } return 0; }
http://www.cnblogs.com/DrunBee/archive/2012/08/12/2634194.html