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 ...
随机推荐
- 对于android拦截短信的一些疑问
最近折腾android4.4短信拦截的问题,要求在app上收到短信的时候弹出提示,并显示的功能. 然后找到了使用broadcastreceiver和contentprovider两种方法,那么问题来了 ...
- BaseAdapter以及对ListView的优化(转)
背景 对于ListView.GridView.Gallery.Spinner等等,它是它们的适配器,直接继承自接口类Adapter的,使用BaseAdapter时需要重写很多方法,其中最重要的当属ge ...
- php declare (ticks = N)
A tick is an event that occurs for every N low-level tickable statements executed by the parser with ...
- 关于AuthorizeAttribute使用
在开发中,假如你只对一个角色进行权限处理,你可以这么写 class ActionAuthAttribute : AuthorizeAttribute { private RoleType _roleT ...
- Struts2 删除后直接直接到List显示页面
package com.sun; import java.util.List; import java.util.Map; import org.hibernate.Session; import o ...
- linux File Handling commands 'ls'.
ref:Linux / Unix Command: ls NAME ls - list directory contents SYNOPSIS ls [OPTION]... [FILE]... DES ...
- jAVA EE里什么是链式调用
链式调用就是每次调用完了过后返回的是自己,比如Hibernate里面执行hql需要设置参数时,每次设置完参数可以继续使用点设置下一个参数http://blog.sina.com.cn/s/blog_4 ...
- 关于Core Data的一些整理(五)
关于Core Data的一些整理(五) 在Core Data中使用NSFetchedResultsController(以下简称VC)实现与TableView的交互,在实际中,使用VC有很多优点,其中 ...
- 《C# 并发编程 · 经典实例》读书笔记
前言 最近在看<C# 并发编程 · 经典实例>这本书,这不是一本理论书,反而这是一本主要讲述怎么样更好的使用好目前 C#.NET 为我们提供的这些 API 的一本书,书中绝大部分是一些实例 ...
- Get URL parameters & values with jQuery
原文: http://jquery-howto.blogspot.jp/2009/09/get-url-parameters-values-with-jquery.html In this post, ...