bzoj1862/1056: [Zjoi2006]GameZ游戏排名系统
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1862
http://www.lydsy.com/JudgeOnline/problem.php?id=1056
【题解】
写到头昏脑涨(逃
写着写着发现不仅要记录权值和哈希值还需要记录插入时间,于是强行开了两个map来映射哈希值->权值,哈希值->插入时间
好像常数很大的样子但是跑的挺快呀。。
记住无论什么操作,都要splay到根,包括询问,因为可以构造一直询问的来卡复杂度。
好像就行了。。先放这份map的吧
# include <map> # include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e5 + 10; const int mod = 1e9+7; struct pa { int v; ull h; pa() {} pa(int v, ull h) : v(v), h(h) {} friend bool operator == (pa a, pa b) { return a.v == b.v && a.h == b.h; } }; int total, ind = 0, tid = 0; map<ull, int> mp, tim; char fys[M][12]; char str[23]; ull bin[23]; struct Splay { int ch[M][2], sz[M], fa[M], tm[M], siz, rt; pa val[M]; int re[M], rn; inline void set() { siz = rn = 0; } inline int newnode() { int x = rn ? re[rn--] : (++siz); fa[x] = ch[x][0] = ch[x][1] = 0, sz[x] = 1; tm[x] = 0; return x; } inline void up(int x) { if(!x) return ; sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]]; } inline void rotate(int x, int &rt) { int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1; if(y == rt) rt = x; else ch[z][ch[z][1] == y] = x; fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z; ch[y][ls] = ch[x][rs]; ch[x][rs] = y; up(y), up(x); } inline void splay(int x, int &rt) { while(x != rt) { int y = fa[x], z = fa[y]; if(y != rt) { if((ch[z][0] == y)^(ch[y][0] == x)) rotate(x, rt); else rotate(y, rt); } rotate(x, rt); } } inline bool cmp(pa t, pa p) { return t.v > p.v; } inline void ins(pa t, int tt) { int x = rt, y, te; while(1) { te = cmp(t, val[x]); y = ch[x][te]; if(!y) { y = newnode(); val[y] = t; tm[y] = tt; fa[y] = x; ch[x][te] = y; break; } x = y; } splay(x, rt); } inline int find(int x, int rk) { if(sz[ch[x][0]] + 1 == rk) return x; if(sz[ch[x][0]] + 1 < rk) return find(ch[x][1], rk - sz[ch[x][0]] - 1); else return find(ch[x][0], rk); } inline int find(int x, pa t, int tt) { if(t.v == val[x].v && tt == tm[x]) return x; if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return find(ch[x][0], t, tt); else return find(ch[x][1], t, tt); } inline int gmax(int x) { while(ch[x][1]) x = ch[x][1]; return x; } inline int gmin(int x) { while(ch[x][0]) x = ch[x][0]; return x; } inline void del(pa t) { int x = find(rt, t, tim[t.h]); splay(x, rt); int pre = gmax(ch[x][0]), nxt = gmin(ch[x][1]); splay(pre, rt); splay(nxt, ch[pre][1]); ch[nxt][0] = 0, fa[x] = 0; ch[x][0] = ch[x][1] = 0; tm[x] = 0; re[++rn] = x; // reuse } inline void INS(pa t) { int tt = tim[t.h]; if(mp.count(t.h)) { int tv = mp[t.h]; del(pa(tv, t.h)); } else ++total; tim[t.h] = ++tid; for (int i=1; str[i]; ++i) fys[tid][i-1] = str[i]; ins(t, tim[t.h]); mp[t.h] = t.v; } inline int findrk(int x, pa t, int tt) { if(t.v == val[x].v && tt == tm[x]) return sz[ch[x][0]] + 1; if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][0], t, tt); else return sz[ch[x][0]] + 1 + findrk(ch[x][1], t, tt); } inline int RANK(ull h) { pa t = pa(mp[h], h); int tt = tim[h]; int ret = findrk(rt, t, tt); int p = find(rt, t, tt); splay(p, rt); return total - ret; } bool fir; inline void prt(int x) { if(!x) return; prt(ch[x][1]); if(fir) fir = 0; else printf(" "); // cout << val[x].h << endl; printf("%s", fys[tm[x]]); prt(ch[x][0]); } inline int PRT(int rk) { int ed = total - rk; rk = total - rk - min(10, total - 1 - rk) + 1;// cout << "rk = " << rk << endl; // debug(rt); int x = find(rt, rk - 1), y = find(rt, ed + 1);// cout << x << ' ' << y << endl; splay(x, rt); splay(y, ch[x][1]); fir = 1; prt(ch[y][0]); puts(""); } inline void debug(int x) { if(!x) return ; debug(ch[x][0]); cout << "x = " << x << ", fa = " << fa[x] << ", ls = " << ch[x][0] << ", rs = " << ch[x][1] << ", val = {" << val[x].v << ", " << val[x].h << "}, sz = " << sz[x] << ", tm = " << tm[x] << endl; debug(ch[x][1]); } }T; inline ull ghash(char *t) { ull ret = 0; for (int i=0; t[i]; ++i) ret = ret + (t[i] - 'A' + 1) * bin[i]; return ret; } inline int toint(char *t) { int ret = 0; for (int i=0; t[i]; ++i) ret = ret * 10 + t[i] - '0'; return ret; } int main() { bin[0] = 1; for (int i=1; i<=20; ++i) bin[i] = bin[i-1] * 20000713; int Q, v; cin >> Q; T.set(); total = 2; // insert v T.siz = 2; T.rt = 1; T.ch[1][0] = T.ch[2][1] = T.ch[2][0] = 0; T.fa[1] = 0; T.val[1] = pa(-2147483648, 233), T.val[2] = pa(2147483647, 233); T.ch[1][1] = 2; T.fa[2] = 1; T.sz[1] = 2, T.sz[2] = 1; while(Q--) { scanf("%s", &str); if(str[0] == '+') { scanf("%d", &v); ull ha = ghash(str+1); T.INS(pa(v, ha)); } else { if(isdigit(str[1])) T.PRT(toint(str+1)); else printf("%d\n", T.RANK(ghash(str+1))); } } return 0; } /* 20 +ADAM 1000000 +BOB 1000000 +TOM 2000000 +CATHY 10000000 ?TOM ?1 +DAM 100000 +BOB 1200000 +ADAM 900000 +FRANK 12340000 +LEO 9000000 +KAINE 9000000 +GRACE 8000000 +WALT 9000000 +SANDY 8000000 +MICK 9000000 +JACK 7320000 ?2 ?5 ?KAINE */
upd: 写了个哈希表,本地跑得贼快
# include <stdio.h> # include <string.h> # include <iostream> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 2.5e5 + 10, N = 2.5e5 + 10; const int mod = 985003; struct pa { int v, h; pa() {} pa(int v, int h) : v(v), h(h) {} friend bool operator == (pa a, pa b) { return a.v == b.v && a.h == b.h; } }; int total, tid = 0; char str[23]; int head[mod + 5], nxt[N], to[N], w[N], tot = 0; char tch[N][12]; inline void add(int u, int v, int tw, char *str) { ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v; for (int i=0; str[i]; ++i) tch[tot][i] = str[i]; w[tot] = tw; } struct Splay { int ch[M][2], sz[M], fa[M], tm[M], siz, rt; pa val[M]; int re[M], rn; inline void set() { siz = rn = 0; } inline int newnode() { int x = rn ? re[rn--] : (++siz); fa[x] = ch[x][0] = ch[x][1] = 0, sz[x] = 1; tm[x] = 0; return x; } inline void up(int x) { if(!x) return ; sz[x] = 1 + sz[ch[x][0]] + sz[ch[x][1]]; } inline void rotate(int x, int &rt) { int y = fa[x], z = fa[y], ls = ch[y][1] == x, rs = ls^1; if(y == rt) rt = x; else ch[z][ch[z][1] == y] = x; fa[ch[x][rs]] = y, fa[y] = x, fa[x] = z; ch[y][ls] = ch[x][rs]; ch[x][rs] = y; up(y), up(x); } inline void splay(int x, int &rt) { while(x != rt) { int y = fa[x], z = fa[y]; if(y != rt) { if((ch[z][0] == y)^(ch[y][0] == x)) rotate(x, rt); else rotate(y, rt); } rotate(x, rt); } } inline bool cmp(pa t, pa p) { return t.v > p.v; } inline void ins(pa t, int tt) { int x = rt, y, te; while(1) { te = cmp(t, val[x]); y = ch[x][te]; if(!y) { y = newnode(); val[y] = t; tm[y] = tt; fa[y] = x; ch[x][te] = y; break; } x = y; } splay(x, rt); } inline int find(int x, int rk) { if(sz[ch[x][0]] + 1 == rk) return x; if(sz[ch[x][0]] + 1 < rk) return find(ch[x][1], rk - sz[ch[x][0]] - 1); else return find(ch[x][0], rk); } inline int find(int x, pa t, int tt) { if(t.v == val[x].v && tt == tm[x]) return x; if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return find(ch[x][0], t, tt); else return find(ch[x][1], t, tt); } inline int gmax(int x) { while(ch[x][1]) x = ch[x][1]; return x; } inline int gmin(int x) { while(ch[x][0]) x = ch[x][0]; return x; } inline void del(pa t, int tim) { int x = find(rt, t, tim); splay(x, rt); int pre = gmax(ch[x][0]), nxt = gmin(ch[x][1]); splay(pre, rt); splay(nxt, ch[pre][1]); ch[nxt][0] = 0, fa[x] = 0; ch[x][0] = ch[x][1] = 0; tm[x] = 0; re[++rn] = x; // reuse } inline void INS(pa t) { int tim = -1, tv, id = -1; for (int i=head[t.h]; i; i=nxt[i]) if(strcmp(tch[i], str+1) == 0) { tim = to[i]; tv = w[i]; id = i; break; } if(id != -1) del(pa(tv, t.h), tim); else ++total; ++tid; tim = tid; if(id != -1) { to[id] = tim; w[id] = t.v; } else add(t.h, tim, t.v, str+1); ins(t, tim); } inline int findrk(int x, pa t, int tt) { if(t.v == val[x].v && tt == tm[x]) return sz[ch[x][0]] + 1; if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][0], t, tt); else return sz[ch[x][0]] + 1 + findrk(ch[x][1], t, tt); } inline int RANK(int h) { int tt, tv; for (int i=head[h]; i; i=nxt[i]) if(strcmp(tch[i], str+1) == 0) { tt = to[i]; tv = w[i]; break; } pa t = pa(tv, h); int ret = findrk(rt, t, tt), x = find(rt, t, tt); splay(x, rt); return total - ret; } bool fir; inline void prt(int x) { if(!x) return; prt(ch[x][1]); if(fir) fir = 0; else printf(" "); // cout << val[x].h << endl; for (int i=head[val[x].h]; i; i=nxt[i]) if(to[i] == tm[x]) { printf("%s", tch[i]); break; } prt(ch[x][0]); } inline int PRT(int rk) { int ed = total - rk; rk = total - rk - min(10, total - 1 - rk) + 1;// cout << "rk = " << rk << endl; // debug(rt); int x = find(rt, rk - 1), y = find(rt, ed + 1);// cout << x << ' ' << y << endl; splay(x, rt); splay(y, ch[x][1]); fir = 1; prt(ch[y][0]); puts(""); } inline void debug(int x) { if(!x) return ; debug(ch[x][0]); cout << "x = " << x << ", fa = " << fa[x] << ", ls = " << ch[x][0] << ", rs = " << ch[x][1] << ", val = {" << val[x].v << ", " << val[x].h << "}, sz = " << sz[x] << ", tm = " << tm[x] << endl; debug(ch[x][1]); } }T; inline int ghash(char *t) { int ret = 0; for (int i=0; t[i]; ++i) ret = 1ll * ret * 20000713 % mod + t[i] - 'A'; return ret % mod; } inline int toint(char *t) { int ret = 0; for (int i=0; t[i]; ++i) ret = ret * 10 + t[i] - '0'; return ret; } int main() { // freopen("rank7.in", "r", stdin); // freopen("rank7-my.out", "w", stdout); int Q, v; cin >> Q; T.set(); total = 2; // insert v T.siz = 2; T.rt = 1; T.ch[1][0] = T.ch[2][1] = T.ch[2][0] = 0; T.fa[1] = 0; T.val[1] = pa(-2147483648, 233), T.val[2] = pa(2147483647, 233); T.ch[1][1] = 2; T.fa[2] = 1; T.sz[1] = 2, T.sz[2] = 1; while(Q--) { scanf("%s", &str); if(str[0] == '+') { scanf("%d", &v); T.INS(pa(v, ghash(str+1))); } else { if(isdigit(str[1])) T.PRT(toint(str+1)); else printf("%d\n", T.RANK(ghash(str+1))); } } return 0; } /* 20 +ADAM 1000000 +BOB 1000000 +TOM 2000000 +CATHY 10000000 ?TOM ?1 +DAM 100000 +BOB 1200000 +ADAM 900000 +FRANK 12340000 +LEO 9000000 +KAINE 9000000 +GRACE 8000000 +WALT 9000000 +SANDY 8000000 +MICK 9000000 +JACK 7320000 ?2 ?5 ?KAINE */