1056: [HAOI2008]排名系统

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 2195  Solved: 623
[Submit][Status][Discuss]

Description

  排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名
记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区
段内的排名记录时,最多返回10条记录。

Input

  第一行是一个整数n(n>=10)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下: +Na
me Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正
整数。 ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。 ?Index 返回自第Index名开始的最多10名
玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。

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
4

HINT

N<=250000

 
 
【题解】
平衡树+哈希
将名字存在哈希表中,每次新插入一条信息就现在哈希表中找看之前有没有记录,如果有就删除,然后插入。
但是有个问题,如果你要删的值和结点值相同但是姓名不同,你怎么知道要删左子树还是右子树??
于是结点还要记录下每个记录时间,删除时只要时间和值相同就行了。
接下来就是平衡树的基本操作了。
 
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<cstdlib>
  6. #include<ctime>
  7. #include<algorithm>
  8. using namespace std;
  9. const int INF=;
  10. int n,root,tot,len,head[INF+];
  11. struct node1{int v,next,time;char ch[];}hash[];
  12. struct node2{int v,time,fix,size,l,r; char ch[];}tr[];
  13. void updata(int p) {tr[p].size=tr[tr[p].l].size+tr[tr[p].r].size+;}
  14. void lturn(int &p) {int c=tr[p].r; tr[p].r=tr[c].l; tr[c].l=p; tr[c].size=tr[p].size; updata(p); p=c;}
  15. void rturn(int &p) {int c=tr[p].l; tr[p].l=tr[c].r; tr[c].r=p; tr[c].size=tr[p].size; updata(p); p=c;}
  16. bool cmp(char a[],char b[]) {for(int i=;i<max(strlen(a),strlen(b));i++) if(a[i]!=b[i]) return ;return ;}
  17. int Hash(char ch[]) {int s=; for(int i=;i<strlen(ch);i++) {s*=; s+=ch[i]-'A'+; s%=INF;} return s;}
  18. void insert(int &p,int v,int time,char ch[])
  19. {
  20. if(!p)
  21. {
  22. p=++len; tr[p].size=; tr[p].v=v; tr[p].time=time; tr[p].fix=rand();
  23. memcpy(tr[p].ch,ch,strlen(ch)); return;
  24. }
  25. tr[p].size++;
  26. if(v<=tr[p].v) {insert(tr[p].l,v,time,ch); if(tr[p].fix>tr[tr[p].l].fix) rturn(p);}
  27. else {insert(tr[p].r,v,time,ch); if(tr[p].fix>tr[tr[p].r].fix) lturn(p);}
  28. }
  29. void del(int &p,int v,int time)
  30. {
  31. if(v==tr[p].v)
  32. {
  33. if(time==tr[p].time)
  34. {
  35. if(tr[p].l*tr[p].r==) p=tr[p].l+tr[p].r;
  36. else if(tr[tr[p].l].fix<tr[tr[p].r].fix) {rturn(p); del(p,v,time);}
  37. else {lturn(p); del(p,v,time);}
  38. }
  39. else if(time>tr[p].time) {tr[p].size--; del(tr[p].l,v,time);}
  40. else {tr[p].size--; del(tr[p].r,v,time);}
  41. }
  42. else if(v<tr[p].v) {tr[p].size--; del(tr[p].l,v,time);}
  43. else {tr[p].size--; del(tr[p].r,v,time);}
  44. }
  45. void work(char ch[],int x,int time)
  46. {
  47. int k=Hash(ch); int i=head[k];
  48. while(i)
  49. {
  50. if(cmp(hash[i].ch,ch))
  51. {
  52. del(root,hash[i].v,hash[i].time);
  53. hash[i].time=time; hash[i].v=x;
  54. insert(root,x,time,ch);
  55. return;
  56. }
  57. i=hash[i].next;
  58. }
  59. tot++;
  60. hash[tot].time=time; hash[tot].v=x;
  61. hash[tot].next=head[k]; head[k]=tot;
  62. memcpy(hash[tot].ch,ch,strlen(ch));
  63. insert(root,x,time,ch);
  64. }
  65. int get(char ch[])
  66. {
  67. int k=Hash(ch);int i=head[k];
  68. while(i)
  69. {
  70. if(cmp(hash[i].ch,ch))return i;
  71. i=hash[i].next;
  72. }
  73. }
  74. int rank(int p,int v,int time)
  75. {
  76. if(p==) return ;
  77. if(tr[p].v==v)
  78. {
  79. if(tr[p].time==time) return tr[tr[p].r].size+;
  80. else if(time<tr[p].time) return rank(tr[p].r,v,time);
  81. else return tr[tr[p].r].size++rank(tr[p].l,v,time);
  82. }
  83. else if(v>tr[p].v) return rank(tr[p].r,v,time);
  84. else return tr[tr[p].r].size++rank(tr[p].l,v,time);
  85. }
  86. void ask1(char ch[])
  87. {
  88. int t=get(ch);
  89. printf("%d\n",rank(root,hash[t].v,hash[t].time));
  90. }
  91. int index(int k,int x)
  92. {
  93. if(tr[tr[k].r].size+==x)return k;
  94. else if(x<=tr[tr[k].r].size)return index(tr[k].r,x);
  95. else return index(tr[k].l,x-tr[tr[k].r].size-);
  96. }
  97. void ask2(char ch[])
  98. {
  99. int s=;
  100. for(int i=;i<strlen(ch);i++){s*=;s+=ch[i]-'';}
  101. for(int i=s;i<=tot&&i<=s+;i++)
  102. {
  103. printf("%s",tr[index(root,i)].ch+);
  104. if(i<tot&&i<s+)printf(" ");
  105. }
  106. printf("\n");
  107. }
  108. int main()
  109. {
  110. freopen("cin.in","r",stdin);
  111. freopen("cout.out","w",stdout);
  112. scanf("%d",&n); char ch[]; int x;
  113. for(int i=;i<=n;i++)
  114. {
  115. scanf("%s",ch);
  116. if(ch[]=='+') {scanf("%d",&x); work(ch,x,i);}
  117. else if(ch[]>='A'&&ch[]<='Z') ask1(ch);
  118. else ask2(ch);
  119. }
  120. return ;
  121. }

【bzoj1056】排名系统的更多相关文章

  1. [BZOJ1056][BZOJ1862][HAOI2008][Zjoi2006]排名系统

    [BZOJ1056][BZOJ1862][HAOI2008][Zjoi2006]排名系统 试题描述 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录 ...

  2. 【BZOJ1056】[HAOI2008]排名系统(Splay)

    [BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...

  3. [bzoj1056] [HAOI2008]排名系统

    Description 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务 ...

  4. BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][ ...

  5. 【BZOJ】1862: [Zjoi2006]GameZ游戏排名系统 & 1056: [HAOI2008]排名系统(treap+非常小心)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1862 http://www.lydsy.com/JudgeOnline/problem.php?id ...

  6. 1056: [HAOI2008]排名系统 - BZOJ

    Description 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务 ...

  7. HNOI2008 and ZJOI2006 排名系统

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1311  Solved: 337[Submit][Statu ...

  8. 数据结构(Splay平衡树):HAOI2008 排名系统

    [HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录 ...

  9. bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1854  Solved: 502[Submit][Statu ...

随机推荐

  1. [转载] PHP升级导致系统负载过高问题分析

    原文:http://chuansongme.com/n/797172 背景 据XX部门兄弟反应, 其在将PHP从5.3.8 升级到5.5.13 时, 开始运行正常, 运行一段时间后, 系统负载变高,达 ...

  2. 通过设置debug_options调试squid

    debug_options用于设置输出到access.log中的调试信息的模块和级别,默认为ALL,1. ALL指所有模块,每个源文件被赋予一个唯一的模块号 1指级别,完全调试的级别为9.很显然,设置 ...

  3. POJ1160 Post Office (四边形不等式优化DP)

    There is a straight highway with villages alongside the highway. The highway is represented as an in ...

  4. plsql基本操作 复制表 导出表 导出表结构 及其导入

    上一片中介绍了安装instantclient +plsql取代庞大客户端的安装,这里说下plsql的基本操作 plsql操作界面图: 1.复制表 语句:create table IGIS_COPY a ...

  5. 【sqlite】基础知识

    最近做一个数控系统的项目,winCE嵌入式操作系统+.Net Compact Framework环境+VS2008开发平台,开发的设备程序部署到winCE系统下的设备中运行.. 个年头,SQLite也 ...

  6. CSS命名规范参考及书写注意事项

    CSS书写顺序 *{ /*显示属性*/ display position float clear cursor … /*盒模型*/ margin padding width height /*排版*/ ...

  7. django的manytomany总结

    from django.db import models class Blog(models.Model): name = models.CharField(max_length=100) tagli ...

  8. vue-router linkActiveClass问题

    在使用vue做移动端的时候,底部四个菜单中当前菜单需要高亮显示,但是由于路由配置的问题导致了下图中的问题: # 首页会一直常亮,不论是否有点击(路由配置如右图) 经过排查,发现问题出现在router中 ...

  9. gerrit简版教程

    设置public key 1.生成密钥:ssh-keygen -t rsa -C "xiaoming" 2.查看是否已经有了ssh密钥:cd ~/.ssh 3.不知道为什么hook ...

  10. redis的安装和类型及基本命令

    一.memcached和redis区别 1. redis 可以存储,memcached用来缓存, 2. 数据类型,memcached只有string:redis有string,链表,哈希结构,集合,有 ...