namespace FHQ{
#define siz(x) ({Node *_a_ = x; _a_ == np ? 0 : _a_->sz; })
struct Node{
Node *ls, *rs;
char val; int pri;
int sz;
void updsz(){
sz = 1 + siz(ls) + siz(rs);
}
} cs[N];
void output(Node *root){
if(root == np) return;
output(root->ls);
putchar(root->val);
#if DEBUG
fflush(stdout);
#endif
output(root->rs);
}
Node* merge(Node* sm, Node* bg){
if(sm == np || bg == np) { return sm == np ? bg : sm; }
if(sm->pri < bg->pri){
sm->rs = merge(sm->rs, bg);
sm->updsz();
return sm;
} else {
bg->ls = merge(sm, bg->ls);
bg->updsz();
return bg;
}
}
void splitrk(Node* root, int rk, Node*& ret1, Node*& ret2){
if(root == np){
ret1 = ret2 = np;
return;
}
if(siz(root->ls) == rk-1){
ret1 = root->ls;
ret2 = root;
root->ls = np;
root->updsz();
} else if(siz(root->ls) < rk-1){
Node* r1, *r2;
splitrk(root->rs, rk-siz(root->ls)-1, r1, r2);
root->rs = r1;
root->updsz();
ret2 = r2;
ret1 = root;
} else {
Node *r1, *r2;
splitrk(root->ls, rk, r1, r2);
root->ls = r2;
root->updsz();
ret1 = r1;
ret2 = root;
}
}
Node* nnod(char v){
static int cnt = 0;
cnt++;
Node* p = &cs[cnt-1];
p->ls = p->rs = np;
p->val = v;
p->pri = rand();
p->sz = 1;
return p;
}
}