#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define N 300010 const int INF=1<<30; int tree[N][2],pa[N],cnt[N],rev[N],val[N]; int Max(int a,int b){ return a>b?a:b; } class splaytree { public: int Root; static int idx; splaytree(){ if(!idx) init(); Root=newnode(-INF);pa[Root]=0; tree[Root][1]=newnode(INF);pa[tree[Root][1]]=Root; update(tree[Root][1]);update(Root); } void update(int t) { //add your code; cnt[t]=cnt[tree[t][0]]+cnt[tree[t][1]]+1; } void push(int t) { //add your code; if(t&&rev[t]) { swap(tree[t][0],tree[t][1]); rev[t]=0; if(tree[t][0]) rev[tree[t][0]]^=1; if(tree[t][1]) rev[tree[t][1]]^=1; } } int newnode(int v){ cnt[++idx]=1;val[idx]=v; pa[idx]=rev[idx]=tree[idx][0]=tree[idx][1]=0; return idx; } void init() { memset(pa,0,sizeof(pa)); memset(rev,0,sizeof(rev)); memset(cnt,0,sizeof(cnt)); memset(tree,0,sizeof(tree)); } //roate function that support left roate action and right roate action void rotate(int t) { int p=pa[t]; int c=(tree[pa[t]][0]==t); tree[p][!c]=tree[t][c]; if(tree[t][c]) pa[tree[t][c]]=p; tree[t][c]=p; pa[t]=pa[p]; if(pa[p])tree[pa[p]][tree[pa[p]][1]==p]=t; pa[p]=t;update(p);update(t); } //the important function that support splay action void splay(int x,int &head) { int p,pp; while(pa[x]&&x!=head){ p=pa[x]; if(p==head) rotate(x); else { pp=pa[p]; if((tree[pp][0]==p)==(tree[p][0]==x)) rotate(p),rotate(x); else rotate(x),rotate(x); } } if(!pa[x]) head=x; } //find node by a value in the tree that root is "head" int find(int v,int head) { int root=head; while(root) { if(v==val[root]) return root; if(v<val[root]) root=tree[root][0]; if(v>val[root]) root=tree[root][1]; } return root; } int findk(int k,int head) { int t; while(head){ push(head);t=cnt[tree[head][0]]; if(k==t+1) return head; else if(k<t+1) head=tree[head][0]; else { k-=t+1; head=tree[head][1]; } } return 0; } //find a node that value is v and splay to root int access(int v,int &head) { int root=head; while(root){ if(val[root]==v) break; if(val[root]>v) root=tree[root][0]; else root=tree[root][1]; } if(root) splay(root,head); return root; } //make a node by value v and insert it int insert(int v,int &head) { int root=head,p=0; int node=newnode(v); while(root){ p=root; if(v<val[root]) root=tree[root][0]; else root=tree[root][1]; } if(!p) head=node; else { pa[node]=p; tree[p][v>=val[p]]=node; splay(node,head); } return node; } //insert a node at the rank k position in the splaytree int insertk(int k,int v,int &head) { int nodek,node=newnode(v); if(!head){ head=node;update(head); } else { nodek=findk(k,head); splay(nodek,head); nodek=findk(k+1,head); splay(nodek,tree[head][1]); tree[nodek][0]=node; pa[node]=nodek; update(node);update(nodek);update(head); } return node; } //join two subtree to a biger tree and return the biger tree's root int join(int a,int b) { if(!a) return b; if(!b) return a; if(!tree[a][1]){ tree[a][1]=b; update(a); return pa[b]=a; } if(!tree[b][0]){ tree[b][0]=a; update(b); return pa[a]=b; } int right=a; while(tree[right][1]) right=tree[right][1]; splay(right,a); tree[a][1]=b; update(a); return pa[b]=a; } //find a node that value is v and split it's two childrens to two splay trees void split(int &head,int node,int &a,int &b) { if(node){ splay(node,head); a=tree[head][0];pa[a]=0; b=tree[head][1];pa[b]=0; } } //find a node that value is v and remove the node from the tree that root is "head" void remove(int node,int &head) { int l; if(node) { splay(node,head);l=cnt[tree[node][0]]; splay(findk(l,head),head); splay(findk(l+2,head),tree[head][1]); tree[tree[head][1]][0]=0; update(tree[head][1]); update(head); } } }; int splaytree::idx=0; void debug(int root) { if(!root) return ; debug(tree[root][0]); printf("%d(%d) ",val[root],root); debug(tree[root][1]); }