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 + ;
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游戏排名系统的更多相关文章
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay
BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...
- 1056/1862. [ZJOI2006]GameZ游戏排名系统【平衡树-splay】
Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...
- bzoj1862: [Zjoi2006]GameZ游戏排名系统
Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...
- 【BZOJ】1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1862 http://www.lydsy.com/JudgeOnline/problem.php?id ...
- bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 502[Submit][Statu ...
- [ZJOI2006]GameZ游戏排名系统
Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...
- [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2487 Solved: 711[Submit][Statu ...
- [洛谷P2584][ZJOI2006]GameZ游戏排名系统
题目大意:同[洛谷P4291][HAOI2008]排名系统(双倍经验) 题解:略 卡点:无 C++ Code: #include <cstdio> #include <map> ...
随机推荐
- how to install pygraphviz on windows 10 with python 3.6
Here's what worked for me: Win 7 AMD64 Install MSFT C++ compiler. Install Anaconda for Win AMD64, Py ...
- bootstrap使用中遇到的坑
一.例如: <div class="form-group"> <label class="control-label col-lg-3"> ...
- OSG学习:转动的小汽车示例
由于只是简单的示例,所以小汽车的模型也比较简单,是由简单的几何体组成. 代码如下: #include <osg\ShapeDrawable> #include <osg\Animat ...
- 【week3】四则运算 单元测试
上一周的四则运算有bug,这次补充正确代码: // 中缀转后缀 public String[] SolveOrder(String[] in, HashMap<String, Integer&g ...
- Windows Server 2012四大版本介绍
今天刚好要尝试安装Windows Server 2012,在网上百度了下发现有4个版本,分别是: Datacenter数据中心版. Standard标准版. Essentials版. Foundati ...
- 关于已部署的WCF服务升级的问题
在日常的开发过程中,我们会经常迭代发布不同的版本,所以WCF服务的接口也会经常处于变动的状态,比如在传递实体类中新加一个字段.修改参数名称等等关于服务升级的问题.但是我们不可能让已发布的版本重新引用新 ...
- SpringBoot2.0(五) CORS跨域
部分跨域 @CrossOrigin注解支持类级别,方法级别添加.可以在controller类或者方法上添加,支持部分接口跨域.在两者上都添加时,方法级别的覆盖类级别的. 属性 说明 origins 允 ...
- VBA练习-打开文件,添加选中项,生成新表
学习VBA,正好给财务制作一个小工具: Sub 打开人员信息表() Dim wb As Workbook, c As Integer Set wb = Workbooks.Open(, True) c ...
- hdu 3191 How Many Paths Are There (次短路径数)
How Many Paths Are There Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java ...
- BZOJ1016:[JSOI2008]最小生成树计数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=1016 现在给出了一个简单无向加权图.你不满足于求出这个图的最小生成树,而希望知道这个图中有多少个不 ...