传送门: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 + ;
const int mod = 1e9+; 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 = , tid = ;
map<ull, int> mp, tim; char fys[M][];
char str[];
ull bin[]; struct Splay {
int ch[M][], sz[M], fa[M], tm[M], siz, rt;
pa val[M];
int re[M], rn; inline void set() {
siz = rn = ;
} inline int newnode() {
int x = rn ? re[rn--] : (++siz);
fa[x] = ch[x][] = ch[x][] = , sz[x] = ; tm[x] = ;
return x;
} inline void up(int x) {
if(!x) return ;
sz[x] = + sz[ch[x][]] + sz[ch[x][]];
} inline void rotate(int x, int &rt) {
int y = fa[x], z = fa[y], ls = ch[y][] == x, rs = ls^;
if(y == rt) rt = x;
else ch[z][ch[z][] == 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][] == y)^(ch[y][] == 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() {
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][]] + == rk) return x;
if(sz[ch[x][]] + < rk) return find(ch[x][], rk - sz[ch[x][]] - );
else return find(ch[x][], 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][], t, tt);
else return find(ch[x][], t, tt);
} inline int gmax(int x) {
while(ch[x][]) x = ch[x][];
return x;
} inline int gmin(int x) {
while(ch[x][]) x = ch[x][];
return x;
} inline void del(pa t) {
int x = find(rt, t, tim[t.h]);
splay(x, rt);
int pre = gmax(ch[x][]), nxt = gmin(ch[x][]);
splay(pre, rt); splay(nxt, ch[pre][]);
ch[nxt][] = , fa[x] = ; ch[x][] = ch[x][] = ; tm[x] = ;
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=; str[i]; ++i) fys[tid][i-] = 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][]] + ;
if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][], t, tt);
else return sz[ch[x][]] + + findrk(ch[x][], 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][]);
if(fir) fir = ;
else printf(" ");
// cout << val[x].h << endl;
printf("%s", fys[tm[x]]);
prt(ch[x][]);
} inline int PRT(int rk) {
int ed = total - rk;
rk = total - rk - min(, total - - rk) + ;// cout << "rk = " << rk << endl;
// debug(rt);
int x = find(rt, rk - ), y = find(rt, ed + );// cout << x << ' ' << y << endl;
splay(x, rt); splay(y, ch[x][]);
fir = ; prt(ch[y][]); puts("");
} inline void debug(int x) {
if(!x) return ;
debug(ch[x][]);
cout << "x = " << x << ", fa = " << fa[x] << ", ls = " << ch[x][] << ", rs = " << ch[x][] << ", val = {" << val[x].v << ", " << val[x].h << "}, sz = " << sz[x] << ", tm = " << tm[x] << endl;
debug(ch[x][]);
} }T; inline ull ghash(char *t) {
ull ret = ;
for (int i=; t[i]; ++i)
ret = ret + (t[i] - 'A' + ) * bin[i];
return ret;
} inline int toint(char *t) {
int ret = ;
for (int i=; t[i]; ++i)
ret = ret * + t[i] - '';
return ret;
} int main() {
bin[] = ;
for (int i=; i<=; ++i) bin[i] = bin[i-] * ;
int Q, v; cin >> Q;
T.set(); total = ;
// insert v
T.siz = ; T.rt = ;
T.ch[][] = T.ch[][] = T.ch[][] = ; T.fa[] = ;
T.val[] = pa(-, ), T.val[] = pa(, );
T.ch[][] = ; T.fa[] = ; T.sz[] = , T.sz[] = ;
while(Q--) {
scanf("%s", &str);
if(str[] == '+') {
scanf("%d", &v);
ull ha = ghash(str+);
T.INS(pa(v, ha));
} else {
if(isdigit(str[])) T.PRT(toint(str+));
else printf("%d\n", T.RANK(ghash(str+)));
}
}
return ;
}
/*
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 + , N = 2.5e5 + ;
const int mod = ; 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 = ; char str[]; int head[mod + ], nxt[N], to[N], w[N], tot = ;
char tch[N][];
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=; str[i]; ++i) tch[tot][i] = str[i];
w[tot] = tw;
} struct Splay {
int ch[M][], sz[M], fa[M], tm[M], siz, rt;
pa val[M];
int re[M], rn; inline void set() {
siz = rn = ;
} inline int newnode() {
int x = rn ? re[rn--] : (++siz);
fa[x] = ch[x][] = ch[x][] = , sz[x] = ; tm[x] = ;
return x;
} inline void up(int x) {
if(!x) return ;
sz[x] = + sz[ch[x][]] + sz[ch[x][]];
} inline void rotate(int x, int &rt) {
int y = fa[x], z = fa[y], ls = ch[y][] == x, rs = ls^;
if(y == rt) rt = x;
else ch[z][ch[z][] == 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][] == y)^(ch[y][] == 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() {
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][]] + == rk) return x;
if(sz[ch[x][]] + < rk) return find(ch[x][], rk - sz[ch[x][]] - );
else return find(ch[x][], 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][], t, tt);
else return find(ch[x][], t, tt);
} inline int gmax(int x) {
while(ch[x][]) x = ch[x][];
return x;
} inline int gmin(int x) {
while(ch[x][]) x = ch[x][];
return x;
} inline void del(pa t, int tim) {
int x = find(rt, t, tim);
splay(x, rt);
int pre = gmax(ch[x][]), nxt = gmin(ch[x][]);
splay(pre, rt); splay(nxt, ch[pre][]);
ch[nxt][] = , fa[x] = ; ch[x][] = ch[x][] = ; tm[x] = ;
re[++rn] = x; // reuse
} inline void INS(pa t) {
int tim = -, tv, id = -;
for (int i=head[t.h]; i; i=nxt[i])
if(strcmp(tch[i], str+) == ) {
tim = to[i]; tv = w[i]; id = i;
break;
}
if(id != -) del(pa(tv, t.h), tim);
else ++total;
++tid; tim = tid;
if(id != -) {
to[id] = tim;
w[id] = t.v;
} else add(t.h, tim, t.v, str+);
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][]] + ;
if(t.v < val[x].v || (t.v == val[x].v && tt > tm[x])) return findrk(ch[x][], t, tt);
else return sz[ch[x][]] + + findrk(ch[x][], t, tt);
} inline int RANK(int h) {
int tt, tv;
for (int i=head[h]; i; i=nxt[i])
if(strcmp(tch[i], str+) == ) {
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][]);
if(fir) fir = ;
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][]);
} inline int PRT(int rk) {
int ed = total - rk;
rk = total - rk - min(, total - - rk) + ;// cout << "rk = " << rk << endl;
// debug(rt);
int x = find(rt, rk - ), y = find(rt, ed + );// cout << x << ' ' << y << endl;
splay(x, rt); splay(y, ch[x][]);
fir = ; prt(ch[y][]); puts("");
} inline void debug(int x) {
if(!x) return ;
debug(ch[x][]);
cout << "x = " << x << ", fa = " << fa[x] << ", ls = " << ch[x][] << ", rs = " << ch[x][] << ", val = {" << val[x].v << ", " << val[x].h << "}, sz = " << sz[x] << ", tm = " << tm[x] << endl;
debug(ch[x][]);
} }T; inline int ghash(char *t) {
int ret = ;
for (int i=; t[i]; ++i)
ret = 1ll * ret * % mod + t[i] - 'A';
return ret % mod;
} inline int toint(char *t) {
int ret = ;
for (int i=; t[i]; ++i)
ret = ret * + t[i] - '';
return ret;
} int main() {
// freopen("rank7.in", "r", stdin);
// freopen("rank7-my.out", "w", stdout);
int Q, v; cin >> Q;
T.set(); total = ;
// insert v
T.siz = ; T.rt = ;
T.ch[][] = T.ch[][] = T.ch[][] = ; T.fa[] = ;
T.val[] = pa(-, ), T.val[] = pa(, );
T.ch[][] = ; T.fa[] = ; T.sz[] = , T.sz[] = ;
while(Q--) {
scanf("%s", &str);
if(str[] == '+') {
scanf("%d", &v);
T.INS(pa(v, ghash(str+)));
} else {
if(isdigit(str[])) T.PRT(toint(str+));
else printf("%d\n", T.RANK(ghash(str+)));
}
}
return ;
}
/*
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
*/

bzoj1862/1056: [Zjoi2006]GameZ游戏排名系统的更多相关文章

  1. BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][ ...

  2. BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay

    BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...

  3. 1056/1862. [ZJOI2006]GameZ游戏排名系统【平衡树-splay】

    Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...

  4. bzoj1862: [Zjoi2006]GameZ游戏排名系统

    Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...

  5. 【BZOJ】1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1862 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  6. bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 502[Submit][Statu ...

  7. [ZJOI2006]GameZ游戏排名系统

    Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...

  8. [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2487  Solved: 711[Submit][Statu ...

  9. [洛谷P2584][ZJOI2006]GameZ游戏排名系统

    题目大意:同[洛谷P4291][HAOI2008]排名系统(双倍经验) 题解:略 卡点:无 C++ Code: #include <cstdio> #include <map> ...

随机推荐

  1. MVC4+EF5 edmx代码分析

    本文分析Entity Framework(EF)从数据库自动生成的模型文件代码(扩展名为edmx). 一. 概述 本文使用的数据库结构尽量简单,只有2个表,一个用户表和一个分公司表(相当于部门表),一 ...

  2. C#中Console.ReadLine()和Console.Read()有何区别?

    Console.Read 表示从控制台读取字符串,不换行. Console.ReadLine 表示从控制台读取字符串后进行换行. Console.Read() Console.ReadLine()方法 ...

  3. isset、is_null、empty的区别

    版本:PHP 5.4 1.isset() :检测变量是否存在,测试如下: $a = false; $b = null; $c; $d = 0; $e = true; var_dump(isset($a ...

  4. 【bzoj2870】最长道路tree 树的直径+并查集

    题目描述 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 输入 第一行N 第二行N个数分别表示1~N的点权v[i] 接下来N-1行每 ...

  5. PyTorch为何如此高效好用?

    C/C++中 Python 扩展对象的简介 你可能知道可以借助 C/C++扩展 Python,并开发所谓的「扩展」.PyTorch 的所有繁重工作由 C/C++实现,而不是纯 Python.为了定义 ...

  6. [bzoj] 1588 营业额统计 || Splay板子题

    原题 给出一个n个数的数列ai ,对于第i个元素ai定义\(fi=min(|ai-aj|) (1<=j<i)\),f1=a1,求\(/sumfi\) Splay板子题. Splay讲解:h ...

  7. BZOJ2659 [Beijing wc2012]算不出的算式 【数形结合】

    题目链接 BZOJ2659 题解 真没想到,, 观察式子 \[\sum\limits_{k = 1}^{\frac{p - 1}{2}} \lfloor \frac{kq}{p} \rfloor\] ...

  8. 运行Jar包程序Shell

    启动: #!/bin/bash set -e JAVA_HOME=/usr/local/java# 检查是否有项目名 appName=$ if [ "$appName" == &q ...

  9. 数组分组chunk的一种写法

    lodash的_.chunk函数可以将数组按照数量分成若干组, 例如: const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; const groupByN ...

  10. ywy_c_asm题

    未知出处 题意: 定义一个无穷长的数列,满足以下性质:$1.X_{2n}=-{X_{n}}$ $2.X_{2n}=(-1)^{(n+1)}*X_{n}$ $3.X_{2n-1}=(-1)^{(n+1) ...