bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)
1056: [HAOI2008]排名系统
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1854 Solved: 502
[Submit][Status][Discuss]
Description
排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。
Input
第
一行是一个整数n(n>=10)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下: +Name Score
上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。 ?Name
查询玩家排名。该玩家的得分记录必定已经在前面上传。 ?Index
返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。
Output
对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。对于?Index格式的请求,应在一行中依次输出从第Index名开始的最多10名玩家姓名,用一个空格分隔。
Sample Input
+ADAM 1000000 加入ADAM的得分记录
+BOB 1000000 加入BOB的得分记录
+TOM 2000000 加入TOM的得分记录
+CATHY 10000000 加入CATHY的得分记录
?TOM 输出TOM目前排名
?1 目前有记录的玩家总数为4,因此应输出第1名到第4名。
+DAM 100000 加入DAM的得分记录
+BOB 1200000 更新BOB的得分记录
+ADAM 900000 更新ADAM的得分记录(即使比原来的差)
+FRANK 12340000 加入FRANK的得分记录
+LEO 9000000 加入LEO的得分记录
+KAINE 9000000 加入KAINE的得分记录
+GRACE 8000000 加入GRACE的得分记录
+WALT 9000000 加入WALT的得分记录
+SANDY 8000000 加入SANDY的得分记录
+MICK 9000000 加入MICK的得分记录
+JACK 7320000 加入JACK的得分记录
?2 目前有记录的玩家总数为12,因此应输出第2名到第11名。
?5 输出第5名到第13名。
?KAINE 输出KAINE的排名
Sample Output
CATHY TOM ADAM BOB
CATHY LEO KAINE WALT MICK GRACE SANDY JACK TOM BOB
WALT MICK GRACE SANDY JACK TOM BOB ADAM DAM
4
HINT
100%数据满足N<=250000
【题解】
名次树+哈希表+处理相同结点。
总的思路就是利用名次树维护排名系统,利用插入时间clock标识每个节点,利用哈希表实现由name到插入时间t以及键值v的映射,这样就可以根据(v,t)在ranktree中实现查找。
其中?name操作可以如下完成:
int ans_cnt,ans[maxn];
void query(Node* o,int pos,int pre) {
if(o==NULL) return ;
int s=(o->ch[1]==NULL? 0:o->ch[1]->s);
int rank=pre+s+1;
if(rank>=pos && rank<=pos+9) {
query(o->ch[1],pos,pre);
ans[ans_cnt++]=o->c;
query(o->ch[0],pos,pre+s+1);
}
else {
if(rank<pos) query(o->ch[0],pos,pre+s+1);
else query(o->ch[1],pos,pre);
}
}
需要注意的有:
1)插入时将相同结点插入右子树,虽然可能会出现通过rotate旋转上来的情况,但其t的相对顺序不会发生改变,因此在遍历中如果遇到相等需要通过t判断所处子树的位置。
2) 行末无空格。
3) 不能以通过不旋转相同结点即破坏堆性质的方法处理相同,刚开始实(zuo)验(si)性试了一下,导致Treap直接退化。
4)bzoj上内存超了就是tle,另外如果要过1862我的代码还需要优化一下hash表以减少空间的浪费。
【代码】
#include<ctime>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<cstdlib>
using namespace std; const int maxn = +;
const int MOD = ; struct Node {
Node *ch[];
int v,r,s,c;
Node(int w,int t) :v(w),c(t) { ch[]=ch[]=NULL; s=; r=rand(); }
int cmp(int x) const {
if(v==x) return -;
return x<v? :;
}
int maintain() {
s=;
if(ch[]!=NULL) s+=ch[]->s;
if(ch[]!=NULL) s+=ch[]->s;
}
};
Node *root;
void rotate(Node* &o,int d) {
Node* k=o->ch[d^]; o->ch[d^]=k->ch[d],k->ch[d]=o;
o->maintain(),k->maintain(),o=k;
}
void insert(Node* &o,int x,int t) {
if(o==NULL) o=new Node(x,t);
else {
int d=x<=o->v? :;
insert(o->ch[d],x,t);
if(o->ch[d]->r > o->r) rotate(o,d^);
}
o->maintain();
}
void remove(Node* &o,int x,int t) {
int d=o->cmp(x);
if(d==- && o->c==t) {
Node *u=o;
if(o->ch[]!=NULL && o->ch[]!=NULL) {
int d2=o->ch[]->r > o->ch[]->r? :;
rotate(o,d2); remove(o->ch[d2],x,t);
}
else {
if(o->ch[]!=NULL) o=o->ch[];
else o=o->ch[]; //ch[0]==NULL && ch[1]==NULL
delete u;
}
}
else {
if(d==-) { if(t<o->c) d=; else d=; }
remove(o->ch[d],x,t);
}
if(o!=NULL) o->maintain();
}
int rank(Node* o,int x,int t) {
if(o==NULL) return -;
int s=o->ch[]==NULL? :o->ch[]->s;
int d=o->cmp(x);
if(d==- && t==o->c) return s+;
else {
if(d==-) { if(t<o->c) d=; else d=; }
if(d==) return s++rank(o->ch[],x,t);
else return rank(o->ch[],x,t);
}
} int n,score,iclock;
char tname[maxn][],s[];
int tt[MOD][],tv[MOD][],size[MOD]; char flag[MOD][][]; int ans_cnt,ans[maxn];
void query(Node* o,int pos,int pre) {
if(o==NULL) return ;
int s=(o->ch[]==NULL? :o->ch[]->s);
int rank=pre+s+;
if(rank>=pos && rank<=pos+) {
query(o->ch[],pos,pre);
ans[ans_cnt++]=o->c;
query(o->ch[],pos,pre+s+);
}
else {
if(rank<pos) query(o->ch[],pos,pre+s+);
else query(o->ch[],pos,pre);
}
}
int hash(char* s) {
int h=;
for(int i=;i<strlen(s);i++) h=h*+s[i]-'A'+,h%=MOD;
return h;
}
int find(char *s) {
int h=hash(s),i=;
while(i<size[h]) { if(strcmp(flag[h][i],s)==) return i; i++;
}
size[h]++; return i;
//cout<<"sz: "<<size[h]<<endl;
} int main() {
freopen("rank.in","r",stdin);
freopen("rank.out","w",stdout);
scanf("%d",&n);
while(n--) {
scanf("%s",s);
int h,r;
if(s[]=='+') {
scanf("%d",&score);
h=hash(s+),r=find(s+);
if(tv[h][r]) remove(root,tv[h][r],tt[h][r]);
insert(root,score,++iclock);
strcpy(tname[iclock],s);
strcpy(flag[h][r],s+);
tt[h][r]=iclock,tv[h][r]=score;
}
else {
if(isalpha(s[])) {
h=hash(s+),r=find(s+);
printf("%d\n",rank(root,tv[h][r],tt[h][r]));
}else {
int pos=;
for(int i=;i<strlen(s);i++) pos=pos*+s[i]-'';
ans_cnt=;
query(root,pos,);
for(int i=;i<ans_cnt;i++) {
printf("%s",tname[ans[i]]+);
if(i<ans_cnt-) putchar(' ');
}
putchar('\n');
}
}
}
return ;
}
bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)的更多相关文章
- bzoj1056: [HAOI2008]排名系统 && 1862: [Zjoi2006]GameZ游戏排名系统
hash 加上 平衡树(名次树). 这道题麻烦的地方就在于输入的是一个名字,所以需要hash. 这个hash用的是向后探查避免冲突,如果用类似前向星的方式避免冲突,比较难写,容易挂掉,但也速度快些. ...
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- 1056/1862. [ZJOI2006]GameZ游戏排名系统【平衡树-splay】
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 1862: [Zjoi2006]GameZ游戏排名系统 & bzoj 1056: [HAOI2008]排名系统
傻叉了一晚上,把t打成x,然后这题神奇在于输出一段数,不足的不用输出,一开始我的是直接找没有后面就退,然后这样会格式错误囧……然后最后zj的还卡了下空间,于是不用string就过了……string毁一 ...
- 【pb_ds】bzoj1056 [HAOI2008]排名系统/bzoj1862 [Zjoi2006]GameZ游戏排名系统
STL裸题,线下AC,bzoj无限RE ing…… #include<cstdio> #include<cctype> #include<iostream> #in ...
- bzoj1056/1862 [Zjoi2006]GameZ游戏排名系统
题目链接:1,2 treap恶心题,不多说 #include<algorithm> #include<iostream> #include<cstdlib> #in ...
- BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay
BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...
- [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2487 Solved: 711[Submit][Statu ...
随机推荐
- 0_Linux_虚拟机安装
虚拟机的安装0Snapshot和clone 系统分区(由硬盘的性能所限制的) 1分区类型: 主分区:最多有4个 扩展分区:最多只能有1个:主分区加扩展分区最多有4个:不能写入数据,只能包含逻辑分区,不 ...
- Codeforces 245G Suggested Friends - 交集set_intersection()
一些人互相是朋友(无向图连一条无向边),现在要添加一个推荐朋友的功能,如果对于x,有y,x与y不是朋友,但是y和x有共同的朋友,并且共同的朋友最多,那么y可以推荐给x.问对于每一个人,有多少人值得推荐 ...
- SPOJ 3048 - DNA Sequences LCS
给出两个字符串(不长于1000),求最长公共子序列,要求:从每个串中取必须取连续k (1<=k<=100)个数 [LCS]一开始自己想用DP加一维[len]用来表示当前已经取了连续len个 ...
- Tips--怎么使用谷歌搜索
修改hosts即可: hosts在哪? windows下:C:\Windows\System32\drivers\etc 管理员身份打开,并将下载好的hosts文件内容,添加到原有的hosts文件末尾 ...
- codevs1044四子连棋(Dfs)
/* 数据范围太小 暴力暴力 Dfs直接 终止条件嘛 就是4中目标棋局 挨着枚举一遍就好了 搜索的起点一定是空格 当然 空格周围有黑有白 黑先走或者白先走答案可能不一样 所以 维护一个b 表示这一步走 ...
- 新闻web小酌
首页如上 类图如下: 添加新闻的方法(dao): public boolean Add(News news) { boolean flag=false; Connection con =getConn ...
- Windows Azure上的Odoo(OpenERP)-1.创建Ubuntu虚拟机,安装PostgreSQL 数据库
前提是您必须拥有Windows Azure的账号,如果没有的话,可以去Windows Azure 中国区网站申请免费试用账号.哈哈,我就是第一批申请的试用账号,感觉自己挺幸运的.申请的过程就不写了,请 ...
- 使用Javascript限制文本框只允许输入数字
很多时候需要用到限制文本框的数字输入,试过许多方法,都不太理想,遂决定自己实现一个来玩玩.曾经使用过的方法通过onkeydown事件来控制只允许数字: <input onkeydown=&quo ...
- DEDECMS织梦列表页每隔N行文章添加一条分隔线
这是给一个朋友做模板的时候,用到的一个小小的技巧,今天正好用上了,以前看到有人问过不知道解决没有,今天整理了一下,本想保存在自己的电脑里,后来一想,不如咱们一起共享一下,也是对织梦的感恩,有好东西就来 ...
- css.day04
1. box 盒子模型 <p> <span> <hr/> <div> css+ div p span css+ xhtml b ...