#include <time.h>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
//By sssSSSay
//On 2017 . 2 . 6
//Today White Eve
#define Lc (o -> Ch[0])
#define Rc (o -> Ch[1])
#define val (o -> v)
#define pre (o -> p)
#define siz (o -> S)
//I'm So Lazy Oh Yes
using namespace std;
const int Maxn = 10001;
struct Treap{
Treap* Ch[2];//The Node's Two Child Tree
int p,v,S;//Priority Value And Size
};
int root = 0,n,x,a[Maxn];
void Update(Treap* &o){//Mountain O's Size
siz = 1;
if(Lc != NULL)siz += Lc -> S;
if(Rc != NULL)siz += Rc -> S;
}
void Rotate(Treap* &o,int d){
Treap* P = o -> Ch[d^1];//P Is A Point That Willing To Be A Root
o -> Ch[d^1] = P -> Ch[d];//Eh......Rotate Should Give P's Child To O
P -> Ch[d] = o;//O Is Going Down So It Is P's Child
Update(o);Update(P);//Points' Size Has Been Changed
o = P;//Use P To Replace O
}
void Insert(Treap* &o,int x){
if(o == NULL){//Insert It To Leaves
o = new Treap();
Lc = Rc = NULL;
pre = rand();val = x;
}
else {//Rotate And Let x Going Up
int d = x < val;
Insert(o -> Ch[d],x);
if( ( pre ) > o -> Ch[d] -> p)Rotate(o,d^1);
}
Update(o);//Mountain O's Size
}
int Find(Treap* o,int x){
while(o != NULL){
if(val == x)return 1;
o = (x < val) ? Rc : Lc ;//Oh It's Easy
}return 0;
}
void Delete(Treap* &o,int x){
if(val == x){//If Find Out X
if(Lc == NULL)o = Rc;
else if(Rc == NULL)o = Lc;//Link Child To Father Straight
else {
int T = (Lc -> p) < (Rc -> p);//Search A Child Tree That Has A Less Pre
Rotate(o,T);Delete(o -> Ch[T],x);//Rotate It And Delete It In Child Tree
}
}
else Delete(o -> Ch[x < val],x);
if(o != NULL)Update(o);
}
int Kth_Min(Treap* o,int k){
if(o == NULL || k <= 0 || k > siz)return 0;//Clearly Can't Find Kth Cases
int S = (Rc == NULL) ? 0 : (Rc -> S);//A Half's Size
if(k == S + 1)return val;//Has Found It
else if(k <= S)return Kth_Min(Rc,k);//Find It In Child Tree
else return Kth_Min(Lc,k - S - 1);
}
int Kth_Max(Treap* o,int k){//The Same As Above
if(o == NULL || k <= 0 || k > siz)return 0;
int S = (Lc == NULL) ? 0 : (Lc -> S);
if(k == S + 1)return val;
else if(k <= S)return Kth_Max(Lc,k);
else return Kth_Max(Rc,k - S - 1);
}
void Print(Treap* o){//Print A Tree
printf("%d ",siz);
if(Lc != NULL)Print(Lc);
if(Rc != NULL)Print(Rc);
}
int main(){
srand(time(NULL));
scanf("%d",&n);
Treap* Root = NULL;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
// if(Root != NULL)printf("%d\n",Root -> v);
Insert(Root,a[i]);
}
// printf("%d %d\n",Root -> v,Root -> p);
// Print(Root);
// Print ==> Print A Treap
// while(true){
// int J = 0;
// scanf("%d%d",&J,&x);
// if(J == 1)printf("%d\n",Find(Root,x));
// else Delete(Root,x);
// }
// Debug -- Find If Exist And If Delete Is Right
// while(true){
// scanf("%d",&x);
// printf("%d %d\n",Kth_Min(Root,x),Kth_Max(Root,x));
// }
// Debug -- Find Kth If Exist Is Right
// while(1);//Just Let My Procedure Stop
return 0;
}
禁止吐槽博主的英文水平