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> ...
随机推荐
- 20145214实验五 Java网络编程及安全
20145214实验五 Java网络编程及安全 实验内容 1.掌握Socket程序的编写: 2.掌握密码技术的使用: 3.设计安全传输系统. 实验步骤 我的结对伙伴是 20145219 宋歌,我负责的 ...
- c# word 删除指定内容
1.首先简单的是获取得到的range,直接rangge.delete() 2.文本框的删除: foreach (Microsoft.Office.Interop.Word.Shape shape in ...
- LintCode-88.最近公共祖先
最近公共祖先 给定一棵二叉树,找到两个节点的最近公共父节点(LCA). 最近公共祖先是两个节点的公共的祖先节点且具有最大深度. 注意事项 假设给出的两个节点都在树中存在 样例 对于下面这棵二叉树 LC ...
- cacti 安装perl 和XML::Simple
一.安装perl #tar zxvf perl-5.20.1.tar.gz #cd perl-5.20.1 #./Configure -de #make #make test #make in ...
- 从实战角度浅析snmp
Snmp Simple Network Management Protocol Snmp最终是为五花八门的网管软件服务的,由于接触的网管软件较少,所以对snmp的理解至今还仅限于初级配置阶段.以下言 ...
- Ubuntu编译内核树
什么是内核树?刚开始我也没弄明白,通过这几天的学习,有所感悟,就说说我的理解吧!从形式上看,内核树与内核源码的目录结构形式是相同的,都是由各个层次的文件目录结构组成,但是其中的具体内容肯定是不同的.从 ...
- bsxfun函数
函数功能:两个数组间元素逐个计算的二值操作 使用方法:C=bsxfun(fun,A,B) 两个数组A合B间元素逐个计算的二值操作,fun是函数句柄或者m文件,也可以为如下内置函数: @plus 加@m ...
- service(ServletRequest req, ServletResponse res) 通用servlet 可以接受任意类型的请求 用于扩展
service(ServletRequest req, ServletResponse res) 通用servlet 可以接受任意类型的请求 用于扩展
- BZOJ 1202 狡猾的商人(带权并查集)
给出了l,r,w.我们就得知了s[r]-s[l-1]=w.也就是说,点l-1和点r的距离为w. 于是可以使用带权并查集,定义dis[i]表示点i到根节点的距离.查询和合并的时候维护一下就OK了. 如果 ...
- Python 静态方法、类方法和属性方法
Python 静态方法.类方法和属性方法 静态方法(staticmethod) staticmethod不与类或者对象绑定,类和实例对象都可以调用,没有自动传值效果,Python内置函数staticm ...