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 ...
随机推荐
- [转] 设计模式 -- Facade
PS:Façade模式注重简化接口,Adapter模式注重转换接口,Bridge模式注重分离接口(抽象)与其实现,Decorator模式注重稳定接口的前提下为对象扩展功能. Facade模式 Faca ...
- js异步的理解---千呼万唤始出来啊!
编译完成后(先分配给变量空间和function(){}命名的函数,var = function(){}这种函数也仅仅只是分配了个空间,还没有赋值个函数给他!),调用了若不是undefined就执行, ...
- asp.net中@page 指令的属性Inherits、Src、CodeBehind区别
在 ASP.NET 中使用代码隐藏方法来设计Web 窗体,可使页代码能够更清晰地从 HTML 内容中分离到完全单独的文件中. <%@ Page language="c#" C ...
- Android VideoView
这两天公司要让做一个播放视频的小Demo,于是网上学习了下VideoView的使用方法. 先看布局文件,很简单 就是一个VideoView和两个ImageView <RelativeLayout ...
- Set Linux starts in multi-user mode as default.
ref: How to start Linux in multiuser mode rather than boot directly into XWindows (X11) steps: Log i ...
- oracle系统包——dbms job用法(oracle定时任务)
用于安排和管理作业队列,通过使用作业,可以使ORACLE数据库定期执行特定的任务. 一.dbms_job涉及到的知识点1.创建job:variable jobno number;dbms_job.su ...
- Qt中QWidget加入到父类QWidget不能显示的问题
最近忙活了半天发现了一个不容易发现的问题,比如我有一个父类的自定义Widget,并且自己设置了Pattle,但这个时候我如果再在当前Widget内部加入自己的widget就不能正常显示,但是加QPus ...
- 11_RHEL安装Maya2015
1. 解压 tar -xvf ./Autodesk_Maya_English_2015_Linux_64bit.tgz 2. 运行 ./setup 2.1补充 如果提示缺少 libpng12.so.0 ...
- Destoon QQ互联一键登录审核不通过的解决方案
在QQ互联上申请帐号之后提交了审核, 后台填写APPID和KEY之后自己申请的QQ号可以正常登录,但QQ互联审核的时候一直审核不通过说是“您的网站审核未通过,原因是“点击QQ登录按钮提示登录失败或出现 ...
- 百度地图api窗口信息自定义
百度地图加载完后,完全可以用dom方法操作,比较常用的就是点击mark的弹窗,利用jQuery可以很快的创建弹窗,需要注意的就是地图都是异步加载,所以绑定时间要用 jQuery 事件 - delega ...