BZOJ1862: [Zjoi2006]GameZ游戏排名系统

Description

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

题解Here!

一眼看去——平衡树!
果断选择了$Splay$大法!
然后我们来对这些操作一个一个分析:

操作一:更新

这个操作显然就是两种情况:

1. 原本没有,那就插入平衡树

2. 原本有,那就先删除原来的,再插入更新后的。

但是怎么找到这个人在平衡树中对应的节点呢?

我们使用了$STL$——已经封装好的$map$!~

有现成的为什么不用呢?

于是这个问题就完美解决了。

操作二:查询排名

用$map$找到对应节点,伸展到根,然后其左子树的大小即为排名。

为什么不减一呢?

因为我们为了操作三,设立了两个哨兵节点。

操作三:查询名字

本蒟蒻一开始的想法是一个一个$kth$,然后$TLE$到爆炸。。。

其实只要把十个节点单独拎出来,按照其后序遍历输出名字即可。

好了,这个题就做完了。

然后本蒟蒻还$RE\times2$,原因是在建立新的节点时,$newnode$函数没有返回值。。。

尴尬到极致。。。

最后,这个题我还手写读入、手写输出的。。。

然后具体的细节看代码吧。

附代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<map>
#define MAXN 1000010
#define MAX 2147483646
using namespace std;
map<string,int> id;
int root=0,size=0;
struct Splay{int f,s,son[2];int v;string name;
}a[MAXN];
inline int read(){int date=0,w=1;char c=0;while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}return date*w;
}
string input_que(int &f,int &val){char ch[15];string name="";val=0;scanf("%s",ch);if(ch[0]=='+'){f=1;int l=strlen(ch);for(int i=1;i<l;i++)name+=ch[i];val=read();return name;}else{if(ch[1]>='0'&&ch[1]<='9'){f=3;int l=strlen(ch);for(int i=1;i<l;i++)val=val*10+ch[i]-'0';return name;}else{f=2;int l=strlen(ch);for(int i=1;i<l;i++)name+=ch[i];return name;}}return name;
}
void output(string name){for(int i=0;i<name.size();i++)putchar(name[i]);putchar(' ');
}
void print(int rt){if(!rt)return;if(a[rt].son[1])print(a[rt].son[1]);output(a[rt].name);if(a[rt].son[0])print(a[rt].son[0]);
}
inline void clean(int rt){a[rt].f=a[rt].s=a[rt].son[1]=a[rt].son[2]=a[rt].v=0;a[rt].name="";
}
inline void pushup(int rt){if(!rt)return;a[rt].s=a[a[rt].son[0]].s+a[a[rt].son[1]].s+1;
}
inline void turn(int rt,int k){int x=a[rt].f,y=a[x].f;a[x].son[k^1]=a[rt].son[k];if(a[rt].son[k])a[a[rt].son[k]].f=x;a[rt].f=y;if(y)a[y].son[a[y].son[1]==x]=rt;a[x].f=rt;a[rt].son[k]=x;pushup(x);pushup(rt);
}
void splay(int rt,int ancestry){while(a[rt].f!=ancestry){int x=a[rt].f,y=a[x].f;if(y==ancestry)turn(rt,a[x].son[0]==rt);else{int k=a[y].son[0]==x?1:0;if(a[x].son[k]==rt){turn(rt,k^1);turn(rt,k);}else{turn(x,k);turn(rt,k);}}}if(ancestry==0)root=rt;
}
inline int newnode(int fa,string name,int v){int rt=++size;a[rt].son[0]=a[rt].son[1]=0;if(fa)a[fa].son[a[fa].v<v]=rt;a[rt].v=v;a[rt].f=fa;a[rt].s=1;a[rt].name=name;id[name]=rt;return rt;
}
void insert(int rt,string name,int v){int fa=0;while(rt){fa=rt;rt=a[rt].son[a[rt].v<v];}rt=newnode(fa,name,v);splay(rt,0);
}
int kth(int rt,int k){if(k<1)k=1;while(1){int y=a[rt].son[0];if(k>a[y].s+1){k-=a[y].s+1;rt=a[rt].son[1];}else if(k<=a[y].s)rt=y;else return rt;}
}
int front_next(int rt,int k){rt=a[rt].son[k];while(a[rt].son[k^1])rt=a[rt].son[k^1];return rt;
}
void remove(int rt){splay(rt,0);int front=front_next(rt,0),next=front_next(rt,1),q;splay(front,0);splay(next,front);q=a[next].son[0];a[next].son[0]=0;clean(q);pushup(next);pushup(front);
}
void update(string name,int v){int x=id[name];remove(x);insert(root,name,v);
}
void get_rank(string name){int x=id[name];splay(x,0);printf("%d\n",a[a[x].son[1]].s);
}
void get_name(int k){k=a[root].s-k;int next=kth(root,k+1),front=kth(root,k-10),q;splay(front,0);splay(next,front);q=a[next].son[0];print(q);putchar('\n');
}
void work(){string name;int f,val;int t=read();while(t--){name=input_que(f,val);switch(f){case 1:{if(id[name])update(name,val);else insert(root,name,val);break;}case 2:{get_rank(name);break;}case 3:{get_name(val);break;}}}
}
void init(){insert(root," ",-1);insert(root," ",MAX);
}
int main(){init();work();return 0;
}

转载于:https://www.cnblogs.com/Yangrui-Blog/p/9863844.html

BZOJ1862: [Zjoi2006]GameZ游戏排名系统相关推荐

  1. BZOJ1862[Zjoi2006]GameZ游戏排名系统【splay+hash】

    [Zjoi2006]GameZ游戏排名系统[Zjoi2006]GameZ游戏排名系统[Zjoi2006]GameZ游戏排名系统 Description: GameZ为他们最新推出的游戏开通了一个网站. ...

  2. bzoj1862 [Zjoi2006]GameZ游戏排名系统

    http://www.elijahqi.win/archives/3043 Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样 ...

  3. BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 Splay

    Splay的基本操作,比较繁琐..... 有个一坑点,sorce会超int 1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 6 ...

  4. 【BZOJ 1862】 [Zjoi2006]GameZ游戏排名系统

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 695  Solved: 265 [Submit] ...

  5. luogu P2584 [ZJOI2006]GameZ游戏排名系统 Splay

    luogu P2584 [ZJOI2006]GameZ游戏排名系统 Splay 实在不想调了QAQ... Code: #include <cstdio> #include <algo ...

  6. bzoj 1862 [Zjoi2006]GameZ游戏排名系统

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 1134  Solved: 429 [Submit ...

  7. [ZJOI2006]GameZ游戏排名系统

    Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...

  8. 1862: [Zjoi2006]GameZ游戏排名系统(Splay)

    Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...

  9. 1056/1862. [ZJOI2006]GameZ游戏排名系统【平衡树-splay】

    Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时 ...

  10. bzoj 1056 1862: [Zjoi2006]GameZ游戏排名系统(Treap+Hash)

    1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2783  Solved: 790 [Submit][Sta ...

最新文章

  1. 如何最大化利用CPU性能创作沉浸式VR体验
  2. php根据IP获取所有地,腾讯IP API
  3. tgp饥荒服务器mod文件在哪,饥荒联机版中客户端mod文件夹在哪?注意不是服务器mod!...
  4. endnote怎么和word关联_endnote x9怎么和word关联?Word中用EndNote X9教程
  5. Qt中线程的简单使用
  6. linux-基本权限-chown-chod
  7. 使用Python扩展库spleeter分离MP3音乐文件中的伴奏和人声
  8. 【leetcode】617. Merge Two Binary Trees
  9. Spring Cloud:Security OAuth2 自定义异常响应
  10. 怎样获得淘宝商品类目API接口
  11. STATA软件进行meta分析,在界面显示meta分析
  12. java实现房屋出租系统
  13. 【软件工程】对软件工程课程的希望及个人目标
  14. 2006公务员考试-杂七杂八常识(1)
  15. 局域网即时通讯Active Messenger 完美破解版本 最新版本破解
  16. android 使用signingConfigs进行打包
  17. 系统动力学视角的智慧城市模型研究
  18. 【C++】Loki库使用
  19. 公司来了个新测试开发,一副毛头小子的样儿,哪想到......
  20. linux虚拟光驱软件下载,虚拟光驱工具DAEMON Tools Ultra下载中文旗舰版6.0.0.1623 - 系统之家...

热门文章

  1. ElasticSearch全文搜索引擎之Linux版安装教程
  2. Mybatis工作中常见关系映射总结
  3. 《软件需求十步走》阅读笔记6
  4. win和linux下DBI安装手册
  5. 重拾C++之虚函数和虚基类以及抽象类
  6. Ajax Session Timeout处理
  7. Java基础算法--排序
  8. 悟透LoadRunner - 调用外部DLL的点点滴滴
  9. Atlas初步了解 [转]
  10. 使用ln命令创建软引用(相对路径与绝对路径)