\(\color{green}{solution}\)
\(fhq \_treap\)模板题.
对于 \(+\) 操作,如果当前人不存在,那么直接加入;如果存在,那么先将他删除,再加入.复杂度\(O(n \log n)\)
对于 \(?\) 操作,如果问人,直接查找名次;如果问名次,先将它前面的\(split\)出去,再把它后面\(10\)个\(split\)
出去,然后输出即可.复杂度均为\(O(n \log n)\).
所以总复杂度是\(O(n \log n)\) 的.具体细节请参见代码.
#include <bits/stdc++.h>
using namespace std;
#define pii pair<int, int>
#define mp make_pair
const int maxn = 250010;
bool operator < (const pii &a, const pii &b) {
return a.first == b.first ? a.second < b.second : a.first > b.first;
}
struct node {node *ls, *rs; pii a; int sz, ky, id;};
node *root, pool[maxn], *pis = pool, *nul, *Bc[maxn];
int bc_top;
inline void init() {
nul = pis; nul->ls = nul->rs = nul; nul->sz = 0; root = nul;
}
node *newnode(int val, int tim, int opt) {
node *k = bc_top ? Bc[bc_top --] : ++ pis;
k->ls = k->rs = nul; k->sz = 1; k->ky = rand(); k->id = opt;
k->a = mp(val, tim); return k;
}
inline void up(node *&x) { x->sz = x->ls->sz + x->rs->sz + 1;}
inline void mrg(node *&c, node *x, node *y) {
if( x == nul || y == nul) {c = x == nul ? y : x; return;}
if( x->ky < y->ky) c = x, mrg(c->rs, x->rs, y);
else c = y, mrg(c->ls, x, y->ls); up(c);
}
inline void spl(node *c, node *&x, node *&y, int ret) {
if( c == nul) { x = y = nul; return;}
if( c->ls->sz+1 <= ret) x = c, spl(c->rs, x->rs, y, ret-c->ls->sz-1);
else y = c, spl(c->ls, x, y->ls, ret); up(c);
}
int find(node *c, pii x) {
if( c->a == x) return c->ls->sz + 1;
if( c->a < x) return c->ls->sz + 1 + find(c->rs, x);
return find(c->ls, x);
}
inline void erase(pii val) {
int rk = find(root, val);
node *x, *y, *z; spl(root, x, y, rk); spl(x, x, z, rk-1);
mrg(root, x, y); Bc[++ bc_top] = z;
}
inline void sp_spl(node *c, node *&x, node *&y, int ret) {
if( c == nul) { x = y = nul; return;}
if( c->a.first >= ret) x = c, sp_spl(c->rs, x->rs, y, ret);
else y = c, sp_spl(c->ls, x, y->ls, ret); up(c);
}
pii Rank[maxn];
int Idc;
inline void insert(int val, int tim, int &id) {
if( id) erase(Rank[id]); else id = ++ Idc;
node *x, *y; Rank[id] = mp(val, tim);
sp_spl(root, x, y, val);
mrg(x, x, newnode(val, tim, id)); mrg(root, x, y);
}
map<string, int> Id;
char buf[maxn][20], ss[20], *tt;
int getnum(char *s) {
int x = 0; for ( ; !isdigit(*s); ++ s);
for ( ; isdigit(*s); ++ s) x = (x << 1) + (x << 3) + (*s & 15);
return x;
}
inline void out(node *x) {
if(x == nul) return; out(x->ls); printf("%s ", buf[x->id]); out(x->rs);
}
int n;
inline void sol1(int rk) {
node *x, *y, *z;
spl(root, x, y, rk-1); spl(y, z, y, 10);
out(z); puts("");
mrg(y, z, y); mrg(root, x, y);
}
int main() {
#ifndef ONLINE_JUDGE
// freopen("1.in","r",stdin);
#endif
init();
scanf("%d", &n);
for ( register int i = 1, x; i <= n; ++ i) {
scanf("%s", ss); tt = ss;
if( *ss == '+') {
++ tt; scanf("%d", &x); insert(x, i, Id[tt]);
int k = Id[tt];
if( k == Idc) memcpy(buf[k], tt, sizeof(buf[k]));
}
else {
++ tt;
if( isdigit(*tt)) sol1(getnum(tt));
else printf("%d\n", find(root, Rank[Id[tt]]));
}
}
return 0;
}