GameZ游戏排名系统
GameZ游戏排名系统
GameZ为他们最新推出的游戏开通了一个网站。世界各地的玩家都可以将自己的游戏得分上传到网站上。这样就可以看到自己在世界上的排名。得分越高,排名就越靠前。当两个玩家的名次相同时,先上传记录者优先。由于新游戏的火爆,网站服务器已经难堪重负。为此GameZ雇用了你来帮他们重新开发一套新的核心。排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。
Input
第一行是一个整数n(n>=10)表示请求总数目。接下来n行每行包含了一个请求。请求的具体格式如下: +Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。 ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。 ?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。输入文件总大小不超过2M。 NOTE:用C++的fstream读大规模数据的效率较低
Output
对于每条查询请求,输出相应结果。对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。对于?Index格式的请求,应在一行中依次输出从第Index名开始的最多10名玩家姓名,用一个空格分隔。
Sample Input
20
+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
2
CATHY TOM ADAM BOB
CATHY LEO KAINE WALT MICK GRACE SANDY JACK TOM BOB
WALT MICK GRACE SANDY JACK TOM BOB ADAM DAM
思路:
用\(FHQ\_treap\ or\ splay\)维护得分对应的名字\(\And\)用另一个平衡树维护名字\(hash\)后对应的得分\(,\)输出时区间提取。(如果单次查询找\(10\)次排名可能会\(TLE\))
当然,为了区分得分相同但名字不同的可以使用时间戳\(or\)随机数
\(\mathfrak{Talk\ is\ cheap,show\ you\ the\ code.}\)
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
# define Type template<typename T>
# define read read1<int>()
Type inline T read1()
{
T t=0;
bool ty=0;
char k;
do k=getchar(),(k=='-')&&(ty=1);while('0'>k||k>'9');
do t=(t<<3)+(t<<1)+(k^'0'),k=getchar();while('0'<=k&&k<='9');
return ty?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
template<typename T>
class FHQ_treap
{
private:
int seed;
public:
int Rand(){return seed=seed*33457+52331314;}
class node
{
public:
node *l,*r;
T k;
int cnt,si,q;
node(){l=r=NULL;cnt=si=1;}
node(T k1,int q1){l=r=NULL;cnt=si=1;k=k1;q=q1;}
}*root;
class Pair
{
public:
node *l,*r;
Pair(){}
Pair(node *a,node *b){l=a;r=b;}
};
private:
void pushup(node *n){n->si=size(n->l)+size(n->r)+n->cnt;}
int size(node *n){return n?n->si:0;}
Pair _split(node *n,T v)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
if(v<n->k)
{
tem=_split(n->l,v);
n->l=tem.r;
tem.r=n;
}
else
{
tem=_split(n->r,v);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
Pair split_(node *n,T v)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
if(v<=n->k)
{
tem=split_(n->l,v);
n->l=tem.r;
tem.r=n;
}
else
{
tem=split_(n->r,v);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
node* merge(node *l,node *r)
{
if(!l or !r)return l?l:r;
node* re;
if(l->q<r->q)l->r=merge(l->r,r),re=l;
else r->l=merge(l,r->l),re=r;
pushup(re);
return re;
}
node* findmin(node* n){while(n->l)n=n->l;return n;}
node* findmax(node* n){while(n->r)n=n->r;return n;}
public:
FHQ_treap(){root=NULL;seed=4088;}
void insert(T ke)
{
Pair tem=_split(root,ke),tem1=split_(tem.l,ke);
if(tem1.r)++tem1.r->cnt,++tem1.r->si;
else tem1.r=new node(ke,Rand());
root=merge(merge(tem1.l,tem1.r),tem.r);
}
void del(T ke)
{
Pair tem=_split(root,ke),tem1=split_(tem.l,ke);
if(tem1.r and --tem1.r->cnt)--tem1.r->si,tem1.l=merge(tem1.l,tem1.r);
root=merge(tem1.l,tem.r);
}
T upper(T ke)
{
Pair tem=_split(root,ke);
T tans=findmin(tem.r)->k;
merge(tem.l,tem.r);
return tans;
}
T lower(T ke)
{
Pair tem=split_(root,ke);
T tans=findmax(tem.l)->k;
merge(tem.l,tem.r);
return tans;
}
int findrank(T ke)
{
Pair tem=split_(root,ke);
int tans=size(tem.l)+1;
merge(tem.l,tem.r);
return tans;
}
T findwho(int n)
{
for(node* i=root;i;)
if(n<=size(i->l))i=i->l;
else if(size(i->l)+i->cnt<n)n-=size(i->l)+i->cnt,i=i->r;
else return i->k;
return 0;
}
};
template<typename T,typename _T>
class FHQ_treap_map
{
private:
int seed,space;
public:
int Rand(){return seed=seed*33457+52331314;}
class node
{
public:
node *l,*r;
T k;_T v;
int cnt,si,q;
node(){l=r=NULL;cnt=si=1;}
node(T k1,_T v1,int q1){l=r=NULL;cnt=si=1;k=k1;v=v1;q=q1;}
}*root;
class Pair
{
public:
node *l,*r;
Pair(){}
Pair(node *a,node *b){l=a;r=b;}
};
private:
void pushup(node *n){n->si=size(n->l)+size(n->r)+n->cnt;}
int size(node *n){return n?n->si:0;}
Pair split(node *n,int ra)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
if(ra<=size(n->l))
{
tem=split(n->l,ra);
n->l=tem.r;
tem.r=n;
}
else
{
tem=split(n->r,ra-size(n->l)-n->cnt);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
Pair _split(node *n,T v)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
if(v<n->k)
{
tem=_split(n->l,v);
n->l=tem.r;
tem.r=n;
}
else
{
tem=_split(n->r,v);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
Pair split_(node *n,T v)
{
if(!n)return Pair(NULL,NULL);
Pair tem;
if(v<=n->k)
{
tem=split_(n->l,v);
n->l=tem.r;
tem.r=n;
}
else
{
tem=split_(n->r,v);
n->r=tem.l;
tem.l=n;
}
pushup(n);
return tem;
}
node* merge(node *l,node *r)
{
if(!l or !r)return l?l:r;
node* re;
if(l->q<r->q)l->r=merge(l->r,r),re=l;
else r->l=merge(l,r->l),re=r;
pushup(re);
return re;
}
node* findmin(node* n){while(n->l)n=n->l;return n;}
node* findmax(node* n){while(n->r)n=n->r;return n;}
public:
FHQ_treap_map(){root=NULL;seed=4088;}
void insert(T ke,_T va)
{
++space;
Pair tem=_split(root,ke);
root=merge(merge(tem.l,new node(ke,va,Rand())),tem.r);
}
void del(T ke)
{
--space;
Pair tem=_split(root,ke),tem1=split_(tem.l,ke);
root=merge(tem1.l,tem.r);
}
T upper(T ke)
{
Pair tem=_split(root,ke);
T tans=findmin(tem.r)->k;
merge(tem.l,tem.r);
return tans;
}
T lower(T ke)
{
Pair tem=split_(root,ke);
T tans=findmax(tem.l)->k;
merge(tem.l,tem.r);
return tans;
}
int findrank(T ke)
{
Pair tem=split_(root,ke);
int tans=size(tem.l)+1;
merge(tem.l,tem.r);
return tans;
}
T findwho(int n)
{
for(node* i=root;i;)
if(n<=size(i->l))i=i->l;
else if(size(i->l)+i->cnt<n)n-=size(i->l)+i->cnt,i=i->r;
else return i->k;
return 0;
}
bool find(T n)
{
for(node* i=root;i;)
if(i->k==n)return 1;
else if(i->k>n)i=i->l;
else i=i->r;
return 0;
}
_T operator [] (const T n)
{
for(node* i=root;i;)
if(i->k==n)return i->v;
else if(i->k>n)i=i->l;
else i=i->r;
return root->v;
}
void pr(node* n,void (*w)(_T) )
{
if(!n)return;
pr(n->l,w);
w(n->v);putchar(' ');
pr(n->r,w);
}
void query(int l,int r,void (*w)(_T) )
{
if(r>space)r=space;
Pair tem=split(root,l-1),tem1=split(tem.r,r-l+1);
pr(tem1.l,w);
merge(tem.l,merge(tem1.l,tem1.r));
}
};
# define ull unsigned long long
# define A pair<int,int>
FHQ_treap_map<A,ull>tr;
char str[11];
FHQ_treap_map<ull,A>ma;
ull Hash(char* str)
{
ull t=0;
while(*str)t=t*27ull+*str-'A'+1,++str;
return t;
}
void print(ull k)
{
if(!k)return;
print(k/27ull);
putchar('A'+k%27ull-1);
}
int main()
{
//fre("1");
int D=0;
for(int T=read;T--;)
{
scanf("%s",str);
ull has,te;
if(*str=='+')
{
has=Hash(str+1);
if(ma.find(has))tr.del(ma[has]),ma.del(has);
ma.insert(has,A(te=-read,++D));
tr.insert(A(te,D),has);
}
else if(*str=='?')
if(*(str+1)<'A')
{
int ke;
sscanf(str+1,"%d",&ke);
tr.query(ke,ke+9,print);
putchar('\n');
}
else if(ma.find(has=Hash(str+1)))
printf("%d\n",tr.findrank(ma[has]));
}
return 0;
}
/*
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
*/
GameZ游戏排名系统的更多相关文章
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- 【洛谷P2584】【ZJOI2006】GameZ游戏排名系统题解
[洛谷P2584][ZJOI2006]GameZ游戏排名系统题解 题目链接 题意: GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在 ...
- 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为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...
- [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 ...
- [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2487 Solved: 711[Submit][Statu ...
随机推荐
- PIE SDK创建金字塔算法
1.算法功能简介 为栅格影像建立了金字塔,这些影像便能快速进行显示.除了在屏幕上显示外,金字塔还包含了很多其他信息.如果没有金字塔,那么在显示时就要访问整理栅格数据集,然后进行大量计算来选择哪些栅格像 ...
- delphi 接口
第四章 接口 前不久,有位搞软件的朋友给我出了个谜语.谜面是“相亲”,让我猜一软件术语.我大约想了一分钟,猜 出谜底是“面向对象”.我觉得挺有趣,灵机一动想了一个谜语回敬他.谜面是“ ...
- Qt隐式共享机制
1.浅拷贝 浅拷贝-引用类型.浅拷贝是指源对象与拷贝对象共用一份实体,仅仅是引用的变量不同(名称不同),对其中任何一个对象的改动都会影响另外一个对象. 2.深拷贝 而深拷贝-值类型.深拷贝是指源对象与 ...
- canvas与svg整理与区别
1.canvas画布(位图) 2.绘制矢量图 1.不要在style中给canvas设置宽高 会有位移差 2. //获取元素 var c=document.getElementById("c& ...
- loadrunner 基本操作
1.录制(录制选项) 2.回放(运行时设置) 3.添加事物 4.参数化 5.内容检查 6.添加集合点 1.在脚本中添加集合点函数如下: lr_rendezvous("集合点") / ...
- 使用脚本安装elasticsearch7.3的记录
使用脚本安装elasticsearch7.3的记录 #!/bin/sh # https://www.elastic.co/guide/en/elasticsearch/reference/curren ...
- 在小程序中实现 Mixins 方案
摘要: 小程序开发技巧 作者:jrainlau 原文:在小程序中实现 Mixins 方案 Fundebug经授权转载,版权归原作者所有. 在原生开发小程序的过程中,发现有多个页面都使用了几乎完全一样的 ...
- Linux shell变量详解
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个 ...
- python语言(六)mock接口开发、发邮件、写日志、新Excel操作
一.urllib模块 urllib模块是一个标准模块,直接import urllib即可,在python3里面只有urllib模块,在python2里面有urllib模块和urllib2模块. url ...
- 【Linux】netstat命令
https://www.cnblogs.com/ftl1012/p/netstat.html这个讲的不错 https://www.linuxprobe.com/netstat-common-metho ...