[BZOJ 1056][HAOI2008]排名系統
阿新 • • 發佈:2018-12-01
\(\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; }