Hash_bzoj1862: [Zjoi2006]GameZ游戏排名系统
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cmath>
- #include <algorithm>
- using namespace std;
- #define maxn 400005
- #define p1 63
- #define p2 103
- #define mod1 1000007
- #define mod2 2000007
- int n,tot,len,need,fact,fa[maxn],son[maxn][],val[maxn],size[maxn];
- char Name[maxn][],name[];
- void read(int &x){
- x=; int f=; char ch;
- for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-;
- for (;isdigit(ch);ch=getchar()) x=x*+ch-''; x*=f;
- }
- struct S{
- int root;
- void prepare(){root=,memset(son,,sizeof(son));}
- int which(int x){
- return son[fa[x]][]==x;
- }
- void updata(int x){
- size[x]=;
- if (son[x][]) size[x]+=size[son[x][]];
- if (son[x][]) size[x]+=size[son[x][]];
- }
- void rotata(int x){
- int y=fa[x],d=which(x),dd=which(y);
- if (fa[y]) son[fa[y]][dd]=x; fa[x]=fa[y];
- fa[son[x][d^]]=y,son[y][d]=son[x][d^];
- fa[y]=x,son[x][d^]=y,updata(y);
- }
- void splay(int x,int goal){
- while (fa[x]!=goal){
- if (fa[fa[x]]==goal) rotata(x);
- else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
- else rotata(x),rotata(x);
- }
- updata(x); if (goal==) root=x;
- }
- void insert(int x){
- int y=root; bool bo;
- if (root==){
- root=x; updata(x);
- return;
- }
- for (;;){
- bo=;
- if (val[x]<=val[y]){
- if (!son[y][]) son[y][]=x,fa[x]=y,updata(x),updata(y),bo=,splay(x,);
- else y=son[y][];
- }else{
- if (son[y][]==) son[y][]=x,fa[x]=y,updata(x),updata(y),bo=,splay(x,);
- else y=son[y][];
- }
- if (bo==) break;
- }
- }
- int prep(int x){
- splay(x,);
- int y=son[x][];
- while (son[y][]) y=son[y][];
- return y;
- }
- void Delete(int x){
- int y=prep(x),z;
- if (y==){
- splay(x,); z=son[x][];
- root=z,son[x][]=son[x][]=fa[x]=size[x]=fa[z]=;
- }else{
- splay(y,),splay(x,y); z=son[x][];
- fa[z]=y,son[y][]=z,updata(y);
- fa[x]=son[x][]=son[x][]=size[x]=;
- }
- }
- int rank(int x){
- splay(x,);
- return size[son[x][]]+;
- }
- int kth(int x){
- int y=root; bool bo;
- for (;;){
- if (size[son[y][]]+==x) return y;
- else if (size[son[y][]]>=x) y=son[y][];
- else x-=size[son[y][]]+,y=son[y][];
- }
- }
- void print(int x){
- if (son[x][]) print(son[x][]);
- fact++;
- for (int i=;i<=Name[x][];i++) printf("%c",Name[x][i]);
- if (fact<need) printf(" ");
- if (son[x][]) print(son[x][]);
- }
- void query(int u,int v){
- int x=kth(u-),y=kth(v+),z; fact=;
- splay(x,),splay(y,x); z=son[y][];
- print(z); puts("");
- }
- }Splay;
- struct hash{
- int now[mod1+],prep[maxn],Ha[maxn][];
- int ha1(){
- int x=;
- for (int i=;i<len;i++){
- x=(x+(int)name[i])%mod1*p1%mod1;
- }
- return x;
- }
- int ha2(){
- int x=;
- for (int i=;i<len;i++){
- x=(x+(int)name[i])%mod2*p2%mod2;
- }
- return x;
- }
- bool exist(){
- int x1=ha1(),x2=ha2(); bool bo=;
- for (int i=now[x1];i;i=prep[i]){
- if (Ha[i][]==x2){
- bo=; break;
- }
- }
- return bo;
- }
- int number(){
- int x1=ha1(),x2=ha2();
- for (int i=now[x1];i;i=prep[i]){
- if (Ha[i][]==x2) return Ha[i][];
- }
- }
- void insert(){
- int x1=ha1(),x2=ha2();
- prep[++tot]=now[x1],now[x1]=tot;
- Ha[tot][]=x2,Ha[tot][]=tot;
- for (int i=;i<len;i++) Name[tot][]++,Name[tot][Name[tot][]]=name[i];
- }
- }Hash;
- int main(){
- char op[];
- memset(size,,sizeof(size));
- read(n),tot=; Splay.prepare();
- val[n+]=-,val[n+]=;
- Splay.insert(n+),Splay.insert(n+);
- for (int w,u,i=;i<=n;i++){
- scanf("%s",op+);
- if (op[]=='+'){
- len=strlen(op+); read(w);
- for (int j=;j<=len;j++) name[j-]=op[j];
- if (!Hash.exist()) Hash.insert(),u=Hash.number(),val[u]=w,Splay.insert(u);
- else{
- u=Hash.number();
- Splay.Delete(u),val[u]=w,Splay.insert(u);
- }
- }else if (op[]=='?'&&!isdigit(op[])){
- len=strlen(op+);
- for (int j=;j<=len;j++) name[j-]=op[j];
- w=Hash.number();
- printf("%d\n",tot-Splay.rank(w)+);
- }else{
- len=strlen(op+); w=;
- for (int j=;j<=len;j++) w=w*+op[j]-'';
- w=tot-w+;
- u=max(,w-+); need=w-u+;
- Splay.query(u+,w+);
- }
- }
- return ;
- }
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862
题意参照题面。
做法:Splay+Hash。
裸的splay,支持插入删除查询排名即可,为什么要用Hash呢,因为如果某玩家上传过记录就得把之前的记录清空,所以我们需要用字符串Hash来判重,字符串我们使用双hash值,一个用来确定地址,第一个来作为val,这样就能降低在哈希表中查找的复杂度,再记录该玩家在Splay树中的标号即可。
splay+Hash。
Hash_bzoj1862: [Zjoi2006]GameZ游戏排名系统的更多相关文章
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- 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 ...
- [洛谷P2584][ZJOI2006]GameZ游戏排名系统
题目大意:同[洛谷P4291][HAOI2008]排名系统(双倍经验) 题解:略 卡点:无 C++ Code: #include <cstdio> #include <map> ...
随机推荐
- Frequently Asked Questions - P-thresholds
Source: http://mindhive.mit.edu/book/export/html 1. What is the multiple-comparison problem? What is ...
- ubuntu12.04禁止单用户本地无密码root登录
1)grub-mkpasswd-pbkdf2 拿到类似grub.pbkdf2.sha512.10000.C093FE6825CDCC2F84934ABC406445E92EE098733C60E6D1 ...
- 【MVC】自定义Scaffold Template
MVC提供了基本的CRUD Scaffold Template模板,创建视图的时候,只要勾选创建一个强类型视图 , 并选择模型类,就可以选择支架模板了,这些模板包括List,Detail,Create ...
- JQuery实现资讯上下滚动悬停效果
第一步:使用repeater绑定一个table. <table width="530" id="rollBar"> <asp:Repeater ...
- 如何拿到半数面试公司Offer——我的Python求职之路
从八月底开始找工作,短短的一星期多一些,面试了9家公司,拿到5份Offer,可能是因为我所面试的公司都是些创业性的公司吧,不过还是感触良多,因为学习Python的时间还很短,没想到还算比较容易的找到了 ...
- 用 Linux自带的logrotate 来管理日志
大家可能都有管理日志的需要,比如定时压缩日志,或者当日志超过一定大小时就自动分裂成两个文件等.最近就接到这样一个小任务.我们的程序用的是C语言,用log4cpp的library来实现日志记录.但是问题 ...
- iostat命令详解
iostat iostat用于输出CPU和磁盘I/O相关的统计信息. 命令格式: iostat [ -c | -d ] [ -k | -m ] [ -t ] [ -V ] [ -x ] [ devic ...
- EF增删改查操作
增 using (StudentEntities ent = new StudentEntities()) { User aNewUser = new User() { Age = , Name = ...
- thinkphp 配置多数据库
1配置文件中配置另一数据库连接信息 例如: 'TestModelConfig' => array( //'配置项'=>'配置值' 'DB_TYPE' => 'mysql', // 数 ...
- 70 sudo-用来以其他身份来执行命令
sudo命令用来以其他身份来执行命令,预设的身份为root.在/etc/sudoers中设置了可执行sudo指令的用户.若其未经授权的用户企图使用sudo,则会发出警告的邮件给管理员.用户使用sudo ...