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

 
 
【题解】
平衡树+哈希
将名字存在哈希表中,每次新插入一条信息就现在哈希表中找看之前有没有记录,如果有就删除,然后插入。
但是有个问题,如果你要删的值和结点值相同但是姓名不同,你怎么知道要删左子树还是右子树??
于是结点还要记录下每个记录时间,删除时只要时间和值相同就行了。
接下来就是平衡树的基本操作了。
 
 #include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<algorithm>
using namespace std;
const int INF=;
int n,root,tot,len,head[INF+];
struct node1{int v,next,time;char ch[];}hash[];
struct node2{int v,time,fix,size,l,r; char ch[];}tr[];
void updata(int p) {tr[p].size=tr[tr[p].l].size+tr[tr[p].r].size+;}
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;}
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;}
bool cmp(char a[],char b[]) {for(int i=;i<max(strlen(a),strlen(b));i++) if(a[i]!=b[i]) return ;return ;}
int Hash(char ch[]) {int s=; for(int i=;i<strlen(ch);i++) {s*=; s+=ch[i]-'A'+; s%=INF;} return s;}
void insert(int &p,int v,int time,char ch[])
{
if(!p)
{
p=++len; tr[p].size=; tr[p].v=v; tr[p].time=time; tr[p].fix=rand();
memcpy(tr[p].ch,ch,strlen(ch)); return;
}
tr[p].size++;
if(v<=tr[p].v) {insert(tr[p].l,v,time,ch); if(tr[p].fix>tr[tr[p].l].fix) rturn(p);}
else {insert(tr[p].r,v,time,ch); if(tr[p].fix>tr[tr[p].r].fix) lturn(p);}
}
void del(int &p,int v,int time)
{
if(v==tr[p].v)
{
if(time==tr[p].time)
{
if(tr[p].l*tr[p].r==) p=tr[p].l+tr[p].r;
else if(tr[tr[p].l].fix<tr[tr[p].r].fix) {rturn(p); del(p,v,time);}
else {lturn(p); del(p,v,time);}
}
else if(time>tr[p].time) {tr[p].size--; del(tr[p].l,v,time);}
else {tr[p].size--; del(tr[p].r,v,time);}
}
else if(v<tr[p].v) {tr[p].size--; del(tr[p].l,v,time);}
else {tr[p].size--; del(tr[p].r,v,time);}
}
void work(char ch[],int x,int time)
{
int k=Hash(ch); int i=head[k];
while(i)
{
if(cmp(hash[i].ch,ch))
{
del(root,hash[i].v,hash[i].time);
hash[i].time=time; hash[i].v=x;
insert(root,x,time,ch);
return;
}
i=hash[i].next;
}
tot++;
hash[tot].time=time; hash[tot].v=x;
hash[tot].next=head[k]; head[k]=tot;
memcpy(hash[tot].ch,ch,strlen(ch));
insert(root,x,time,ch);
}
int get(char ch[])
{
int k=Hash(ch);int i=head[k];
while(i)
{
if(cmp(hash[i].ch,ch))return i;
i=hash[i].next;
}
}
int rank(int p,int v,int time)
{
if(p==) return ;
if(tr[p].v==v)
{
if(tr[p].time==time) return tr[tr[p].r].size+;
else if(time<tr[p].time) return rank(tr[p].r,v,time);
else return tr[tr[p].r].size++rank(tr[p].l,v,time);
}
else if(v>tr[p].v) return rank(tr[p].r,v,time);
else return tr[tr[p].r].size++rank(tr[p].l,v,time);
}
void ask1(char ch[])
{
int t=get(ch);
printf("%d\n",rank(root,hash[t].v,hash[t].time));
}
int index(int k,int x)
{
if(tr[tr[k].r].size+==x)return k;
else if(x<=tr[tr[k].r].size)return index(tr[k].r,x);
else return index(tr[k].l,x-tr[tr[k].r].size-);
}
void ask2(char ch[])
{
int s=;
for(int i=;i<strlen(ch);i++){s*=;s+=ch[i]-'';}
for(int i=s;i<=tot&&i<=s+;i++)
{
printf("%s",tr[index(root,i)].ch+);
if(i<tot&&i<s+)printf(" ");
}
printf("\n");
}
int main()
{
freopen("cin.in","r",stdin);
freopen("cout.out","w",stdout);
scanf("%d",&n); char ch[]; int x;
for(int i=;i<=n;i++)
{
scanf("%s",ch);
if(ch[]=='+') {scanf("%d",&x); work(ch,x,i);}
else if(ch[]>='A'&&ch[]<='Z') ask1(ch);
else ask2(ch);
}
return ;
}

【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. Leetcode 944. Delete Columns to Make Sorted

    class Solution: def minDeletionSize(self, A: List[str]) -> int: ans = 0 for j in range(len(A[0])) ...

  2. 请求URL中有body怎么使用jmeter进行接口测试

    业务场景: 微信内免费领取激活码 1.点击“免费领取”按钮调取的接口 2.URL如下 https://yxyapi2.drcuiyutao.com/yxy-api-gateway/api/json/v ...

  3. linux rm删除含有特殊符号目录或者文件

    想要删除time$1.class,用rm time$1.class是不行的,可以用 rm time"$"1.class 删掉   假设Linux系统中有一个文件名叫“-polo”. ...

  4. HTTrack - 克隆任意网站

    HTTrack可以克隆指定网站-把整个网站下载到本地. 可以用在离线浏览上,也可以用来收集信息(甚至有网站使用隐藏的密码文件). 一些仿真度极高的伪网站(为了骗取用户密码),也是使用类似工具做的. K ...

  5. DEV控件 皮肤问题

    今天用cnPack清理了下整个工程的引用单元,清理完,问题来了,TcxPageControl不透明了. 折腾了一会,找到原因,清理单元时将dxSkinscxPCPainter也清掉了,导致皮肤无法正常 ...

  6. HDU - 5829:Rikka with Subset (NTT)

    As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some mat ...

  7. HDU - 5936: Difference(暴力:中途相遇法)

    Little Ruins is playing a number game, first he chooses two positive integers yy and KK and calculat ...

  8. 使用wlan接收器经常重新登录怎么办

    wlan接收器是一个大功率的网卡,能够接受耿远距离的无线网络,在农村和乡镇很普及,很多家庭里都是用这个装置来接受远距离的CMCC信号.但是在使用的时候会经常出现一些问题,例如我们登陆以后,还没等上网就 ...

  9. 在Git远程管理项目

    新建repository 本地目录下,在命令行里新建一个代码仓库(repository) 里面只有一个README.md 命令如下: touch README.md        git init 初 ...

  10. datetimebox

    $.extend($.fn.datagrid.defaults.editors, { datetimebox: {// datetimebox就是你要自定义editor的名称 init: functi ...