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 */

最新文章

  1. ngx_http_fastcgi_module模块.md
  2. 用Node.js发送邮件
  3. eclipse Swt编程—窗口小部件widget
  4. poj 1655
  5. Java中线程的生命周期
  6. Windows RabbitMQ 命令
  7. 浅析Java.lang.ProcessBuilder类
  8. 积累一点ctf需要掌握的常见脚本知识
  9. vb6动态创建webbrowser
  10. jQuery实现动态添加和删除一个div
  11. [codevs1380]没有上司的舞会
  12. JavaWeb学习笔记之JSP(一)
  13. 初学Pexpect
  14. 关于启动调试时,总是启动多个web端口的问题
  15. Day7 小练习(统计初始化数据的次数和对象之间的交互)
  16. java date总结
  17. eclipse jsp:useBean搞死人了。
  18. Python之部分基础知识点汇总
  19. jersey中的405错误 method not allowed
  20. I2C三态门Verilog

热门文章

  1. windows 10 配置Java 环境变量(5步骤)
  2. Node.js返回JSON
  3. VMware + CentOS 7搭建环境(一)
  4. 关于IOS AFNetWorking内存泄漏的问题
  5. JVM参数最佳实践:元空间的初始大小和最大大小
  6. Java字符串——String深入
  7. Eclipse properties配置文件中文乱码设置
  8. properties文件属性值通过xml文件为 java entity属性赋值
  9. 彻底理解webgl
  10. PAT 乙级 1021.个位数统计 C++/Java