2021.12.07 P4291 [HAOI2008]排名系统(Treap)
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)的更多相关文章
- P4291 [HAOI2008]排名系统
题目描述 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回 ...
- [洛谷P4291][HAOI2008]排名系统
题目大意:三种操作: $+Name\;Socore:$上传最新得分记录,把以前的记录删除. $?Name:$ 查询玩家排名.如果两个玩家的得分相同,则先得到该得分的玩家排在前面. $?Index:$ ...
- 2021.12.07 [TJOI2013]最长上升子序列(Treap+DP)
2021.12.07 [TJOI2013]最长上升子序列(Treap+DP) https://www.luogu.com.cn/problem/P4309 题意: 给定一个序列,初始为空.现在我们将1 ...
- bzoj 1056 [HAOI2008]排名系统(1862 [Zjoi2006]GameZ游戏排名系统)
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 502[Submit][Statu ...
- 数据结构(Splay平衡树):HAOI2008 排名系统
[HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录 ...
- [HAOI2008]排名系统& [Zjoi2006]GameZ游戏排名系统
1056: [HAOI2008]排名系统 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2487 Solved: 711[Submit][Statu ...
- BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay
BZOJ_1862_[Zjoi2006]GameZ游戏排名系统&&BZOJ_1056_[HAOI2008]排名系统_Splay Description 排名系统通常要应付三种请求:上传 ...
- 【BZOJ1056】[HAOI2008]排名系统(Splay)
[BZOJ1056][HAOI2008]排名系统(Splay) 题面 BZOJ 洛谷 题解 \(Splay\)随便维护一下就好了,至于名字什么的,我懒得手写哈希表了,直接哈希之后拿\(map\)压. ...
- 2021.12.06 P2511 [HAOI2008]木棍分割(动态规划)
2021.12.06 P2511 [HAOI2008]木棍分割(动态规划) https://www.luogu.com.cn/problem/P2511 题意: 有n根木棍, 第i根木棍的长度为 \( ...
随机推荐
- django处理跨域
django处理Ajax跨域访问时使用javascript进行ajax访问的时候,出现如下错误 出错原因:javascript处于安全考虑,不允许跨域访问.下图是对跨域访问的解释: 概念: 这里说的j ...
- springmvc对前台参数的接收
一.基本数据类型的接收 代码: @RequestMapping("/selectRegion") public BaseResult<?> method(String ...
- JDBC 中如何进行事务处理?
Connection 提供了事务处理的方法,通过调用 setAutoCommit(false)可以设置 手动提交事务:当事务完成后用 commit()显式提交事务:如果在事务处理过程中 发生异常则通过 ...
- css文本溢出解决方案
1.普通单行截断省略 overflow:hidden; 文字长度超出限定宽度,则隐藏超出的内容) text-overflow:ellipsis;(设置文字在一行显示,不能换行) white-space ...
- CPU架构:CPU架构详细介绍
1 概述 CPU架构是CPU商给CPU产品定的一个规范,主要目的是为了区分不同类型的CPU.目前市场上的CPU分类主要分有两大阵营,一个是intel.AMD为首的复杂指令集CPU,另一个是以IBM.A ...
- 如何正确的阅读Datasheet?
不仅仅是芯片,包括工具.设备几乎任何电子产品,都需要去阅读它的datasheet,除了包括最低.最高要求,特点,建议和用途及其兼容的设备等等,更重要的是原厂商以一个成功者的身份去告诉你一些注意事项. ...
- Web存储之LocalStorage初探
Web存储之LocalStorage初探 HTML5的发布和定稿为前端界带来巨大的变化,新增的API和特性给业务带来了更多可能性,让用户体验拥有了更可能的丰富. · HTML Geolocation ...
- python计算项目净现值和内部回报率
代码: import numpy as np from numpy import irr import warnings def project(number, period_list): rate ...
- 大数据学习之路之ambari配置(四)
试了很多遍,内存还是不够,电脑不太行的,不建议用ambari!!! 放弃了
- Android点击按钮退出程序并提醒
效果展示: MainActivity.java import androidx.appcompat.app.AppCompatActivity; import android.app.AlertDia ...