2021.12.07 P4291 [HAOI2008]排名系统(Treap)

https://www.luogu.com.cn/problem/P4291

双倍经验:

https://www.luogu.com.cn/problem/P2584

题意:

输入n行,每次输入是一下三种情况之一:

+Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。

?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。如果两个玩家的得分相同,则先得到该得分的玩家排在前面。

?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。

分析:

有分数(名字)找排名、有排名找分数(名字)——平衡树。

不过对于分数的处理有一些特殊:

同样的分数,谁先输入谁在前。蓝书介绍了一种方法:

一般来说,如果有两个需要优化的量 \(v_1\) , \(v_2\) ,要求首先满足 \(v_1\) 最小,在 \(v_1\) 相同的情况下 \(v_2\) 最小,则可以把二者合并成一个量 \(M\times v_1+v_2\) ,其中 \(M\) 是一个比 \(v_2\) 的最大理论值和 \(v_1\) 的最小理论值之差还要大的数。

这题 \(M\) 可以取250000,不过因为题上要求越高排名越靠前,记得再加负号。

代码如下:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<map>
#define IOS ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std; #define int long long
const int N=250010;
const int M=250000;
int n;
int cnt,root,tot,son[N][2],val[N],key[N],sizei[N],same[N];
int top;
map<string,long long>name_num;
map<long long,string>num_name;
map<int,string>id_name; inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
inline void update(int x){
sizei[x]=sizei[son[x][0]]+sizei[son[x][1]]+same[x];
}
inline void rotate(int &x,int flag){
int y=son[x][flag^1];
int change=son[y][flag];
son[x][flag^1]=change;
son[y][flag]=x;
update(x);
update(y);
x=y;
}
inline void insert(int &x,int vali){
if(!x){
x=++cnt;++tot;
sizei[x]=same[x]=1;
val[x]=vali;key[x]=rand();
return ;
}
if(val[x]==vali)return (void)(++sizei[x],++same[x]);
int flag=val[x]<vali;
insert(son[x][flag],vali);
if(key[son[x][flag]]>key[x])rotate(x,flag^1);
update(x);
}
inline void deletei(int &x,int vali){
if(!x)return ;
int flag=val[x]==vali?-1:(val[x]<vali?1:0);
if(flag!=-1)deletei(son[x][flag],vali);
else{
if(!son[x][0]&&!son[x][1]){
--sizei[x];--same[x];
if(!same[x])x=0,--tot;
}else if(son[x][0]&&!son[x][1]){
rotate(x,1);
deletei(son[x][1],vali);
}else if(!son[x][0]&&son[x][1]){
rotate(x,0);
deletei(son[x][0],vali);
}else if(son[x][0]&&son[x][1]){
flag=key[son[x][0]]>key[son[x][1]];
rotate(x,flag);
deletei(son[x][flag],vali);
}
}
update(x);
}
inline int score_rank(int x,int k){
if(!x)return 0;
if(val[x]==k)return sizei[son[x][0]]+1;
else if(val[x]>k)return score_rank(son[x][0],k);
else if(val[x]<k)return sizei[son[x][0]]+same[x]+score_rank(son[x][1],k);
}
inline int rank_score(int x,int k){
if(!x)return 0;
if(sizei[son[x][0]]>=k)return rank_score(son[x][0],k);
else if(sizei[son[x][0]]+same[x]>=k)return val[x];
else return rank_score(son[x][1],k-sizei[son[x][0]]-same[x]);
}
inline int change(string s){
int num=0;
for(int i=0;i<s.length();i++)num=num*10+s[i]-'0';
return num;
} signed main(){
n=read();
for(int i=1;i<=n;i++){
char op;//=getchar();
cin>>op;
//cout<<"i "<<i<<" "<<op<<endl;
if(op=='+'){
string s;cin>>s;
int x=read();
x=x*M-i;
x*=-1;//!
//cout<<s<<" "<<x<<endl;//
if(name_num[s])deletei(root,name_num[s]);
insert(root,x);
name_num[s]=x;num_name[x]=s;
//cout<<num_name[x]<<" "<<name_num[s]<<endl;//
}else if(op=='?'){
string s;cin>>s;
if(s[0]<'0'||s[0]>'9'){
//cout<<s<<" "<<name_num[s]<<" Case 1"<<endl;
cout<<score_rank(root,name_num[s])<<endl;
}else{
int start=change(s);
//cout<<s<<" "<<start<<" "<<tot<<endl;//
for(int j=start;j<=min(start+9,tot);j++)
cout<<num_name[rank_score(root,j)]<<" ";
cout<<endl;
}
}
/*cout<<"find eleveni "<<endl;
for(int j=1;j<=tot;j++){
int x=rank_score(root,j);
cout<<x<<" "<<num_name[x]<<endl;
}
cout<<endl;*/
}
return 0;
}

2021.12.07 P4291 [HAOI2008]排名系统(Treap)的更多相关文章

  1. P4291 [HAOI2008]排名系统

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

  2. [洛谷P4291][HAOI2008]排名系统

    题目大意:三种操作: $+Name\;Socore:$上传最新得分记录,把以前的记录删除. $?Name:$ 查询玩家排名.如果两个玩家的得分相同,则先得到该得分的玩家排在前面. $?Index:$ ...

  3. 2021.12.07 [TJOI2013]最长上升子序列(Treap+DP)

    2021.12.07 [TJOI2013]最长上升子序列(Treap+DP) https://www.luogu.com.cn/problem/P4309 题意: 给定一个序列,初始为空.现在我们将1 ...

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

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

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

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

  6. [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统

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

  7. BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay

    BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...

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

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

  9. 2021.12.06 P2511 [HAOI2008]木棍分割(动态规划)

    2021.12.06 P2511 [HAOI2008]木棍分割(动态规划) https://www.luogu.com.cn/problem/P2511 题意: 有n根木棍, 第i根木棍的长度为 \( ...

随机推荐

  1. IIS短文件猜解

    1.IIS短文件漏洞 Microsoft IIS 短文件/文件夹名称信息泄漏最开始由Vulnerability Research Team(漏洞研究团队)的Soroush Dalili在2010年8月 ...

  2. sublime settings

    { "font_face": "Monaco", // 编辑器的字体 "font_size": 13, // 字号 "highli ...

  3. windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看

    windows server 2019 域控批量新增不用,只看这一篇就够了,别的不用看 1. 新建excel表格 A B C D E 姓 名 全名 登录名 密码 李 四 李四 李四 test123!@ ...

  4. Java基础知识 String StringBuffer StringBuilder三者的区别(面试题)

    相同点:String.StringBuffer.StringBuilder最终底层存储与操作的都是char数组,StringBuffer和StringBuilder都继承了AbstractString ...

  5. C++11移动语义之一(基本概念)

    摘要 移动语义是C++11的新特性之一,利用移动语义可以实现对象的移动而非拷贝.在某些情况下,可以大幅度的提升性能.本文将介绍C++11移动语义中的一些基本概念. 表达式 表达式是由一个或者多个运算对 ...

  6. CEPH-2:rbd功能详解及普通用户应用ceph集群

    ceph集群rbd使用详解 一个完整的ceph集群,可以提供块存储.文件系统和对象存储. 本节主要介绍rbd存储功能如何灵活的使用,集群背景: $ ceph -s cluster: id: 53717 ...

  7. Java中的序列化Serialable

    Java中的序列化Serialable https://blog.csdn.net/caomiao2006/article/details/51588838

  8. kafka unclean 配置代表啥,会对 spark streaming 消费有什么影响?

    unclean.leader.election.enable 为true的话,意味着非ISR集合的broker 也可以参与选举,这样有可能就会丢数据,spark streaming在消费过程中拿到的 ...

  9. java的arrays

    java.util.Arrays 是一个于数组相关的工具类,里面提供大佬的静态方法,用来实现数组常见的操作 public staic String toString(数组)  将参数数组编程字符串,默 ...

  10. 你对 Spring Boot 有什么了解?

    事实上,随着新功能的增加,弹簧变得越来越复杂.如果必须启动新的 spring 项 目,则必须添加构建路径或添加 maven 依赖项,配置应用程序服务器,添加 spring 配置.所以一切都必须从头开始 ...