1. 程式人生 > >Buy Tickets[Splay]

Buy Tickets[Splay]

傳送門

Splay直接維護就可以了


#include<iostream>
#include<cstdio>
#define N 200005
#define lc t[x].ch[0]
#define rc t[x].ch[1]
using namespace std;
struct Splay{int ch[2],fa,val,size;}t[N];
int n,rt,tot;
int read(){
	int cnt=0;char ch=0;
	while(!isdigit(ch))ch=getchar();
	while(isdigit(ch))cnt=cnt*10+(ch-'0'),ch=getchar();
	return cnt;
}
void Clear(){
	for(int i=0;i<=tot;i++)
		t[i].ch[0]=t[i].ch[1]=t[i].fa=t[i].val=t[i].size=0;
	rt = tot = 0;
}
void Pushup(int x){
	t[x].size = t[lc].size + t[rc].size + 1;
}
void rotate(int x){
	int y=t[x].fa , z=t[y].fa;
	int k=t[y].ch[1]==x;
	t[z].ch[t[z].ch[1]==y] = x , t[x].fa = z;
	t[y].ch[k] = t[x].ch[k^1] , t[t[x].ch[k^1]].fa=y;
	t[x].ch[k^1]=y , t[y].fa=x;
	Pushup(y),Pushup(x);
}
void Splay(int x,int goal){
	while(t[x].fa != goal){
		int y=t[x].fa , z=t[y].fa;
		if(z!=goal)
			(t[y].ch[0]==x)^(t[z].ch[0]==y) ? rotate(x) : rotate(y);
		rotate(x);
	}if(!goal) rt=x;
}
void Special_Insert(int x,int p,int val){
	int fa=0; 
	while(x) fa=x , x=t[x].ch[p];
	t[fa].ch[p] = ++tot; 
	t[tot].size=1 , t[tot].val=val , t[tot].fa=fa;
	Splay(tot,0);
}
int Find(int x,int k){
	if(t[lc].size >= k) return Find(lc,k);
	else if(t[lc].size+1 < k) return Find(rc,k-t[lc].size-1);
	else return x; 
}
void Insert(int x,int val){
	int pre=Find(rt,x) , suf=Find(rt,x+1);
	Splay(pre,0) , Splay(suf,pre); 
	t[suf].ch[0] = ++tot;
	t[tot].val = val , t[tot].size = 1 , t[tot].fa=suf;
	Pushup(suf) , Pushup(pre);
}
void Cout(int x){if(lc) Cout(lc); printf("%d ",t[x].val); if(rc) Cout(rc);}
int main(){
	while(scanf("%d",&n)!=EOF){
		n--; Clear();
		int x=read(),val=read();
		t[++tot].val = val , t[tot].size = 1 , rt=1;
		while(n--){
			int x=read(),val=read();
			if(x==0 || x==tot) Special_Insert(rt,(x!=0),val);
			else Insert(x,val);
		}Cout(rt); printf("\n");
	}return 0;
}