传送门: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. c# 委托初窥

    1.委托可以把方法当作参数在另一个方法中传递和调用 ,委托是方法的快捷方式. 2.委托是一个类. private void BeginSocketThread() { try { IPEndPoint ...

  2. 《梦断代码Dreaming In Code》阅读笔记(二)

    这段时间一口气读了5章,所以想着现在一块写阅读笔记. 在阅读的这段时间,我一直是晚上进行阅读,很多时候都是读完一看已经一个小时了,效果还不错.闲话不表,说说阅读心得. 关于底层语言或是低级语言,我之前 ...

  3. Android UI 设计之 TextView EditText 组件属性方法最详细解析

    . 作者 :万境绝尘  转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/18964835 . TextView 相关类的继承结构 ...

  4. MFC最基本动作(如创建窗口,点击取消等)函数的执行顺序

    一.MFC应用程序中处理消息的顺序: 1.AfxWndProc()       该函数负责接收消息,找到消息所属的CWnd对象,然后调用AfxCallWndProc2.AfxCallWndProc() ...

  5. TCP源码—系统调用

    1.socket SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) sys_socket->sock_create-& ...

  6. Winform 子窗体设置刷新父窗体

    方法1:所有权法 父窗体:Form1    子窗体:Form2 //Form1:窗体代码 //需要有一个公共的刷新方法 public void Refresh_Method() { //... } / ...

  7. Android基础------SQLite数据库(一)

    1.SQLite介绍 SQLite是一款非常流行的嵌入式数据库,它支持SQL操作,并且只用很少的内存. Android在运行时集成了SQLite,所有每个Android应用程序都可以使用SQLLite ...

  8. JDK各个版本比较 JDK5~JDK9

    JDK5 自动装箱与拆箱: 枚举 静态导入,如:import staticjava.lang.System.out 可变参数(Varargs) 内省(Introspector),主要用于操作JavaB ...

  9. 第23天:js-数据类型转换

    一.padding1.内边距会影响盒子大小2.行内元素,尽量不用上下的padding和margin3.块元素嵌套块元素.子级会继承父级的宽度,高度由内容决定.如果给子级再设置padding,不会影响盒 ...

  10. RT-thread内核对象标志flag总结

    一.内核标志flag 在内核对象控制块中有一个标志成员flag(rt_uint8_t flag; ),这个标志在不同有内核对象中具有不同的含义.rt-thread的内核对象有定时器.线程.信号量.互斥 ...