首页 > 代码库 > BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

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

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1318  Solved: 498
[Submit][Status][Discuss]

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

复习一下treap
因为同样v先提交排名靠前,所以需要记录时间
v小到大,tm大到小
treap操作变化的地方就是v相同时要讨论时间
插入一个人先在哈希表里找他,然后删除它在插入新的
注意这样的话是倒着排名
 
注意:
1.旋转别写错
2.拷贝字符串memcpy(tar,s,strlen(s))不是sizeof(s)........
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>using namespace std;#define lc t[x].l#define rc t[x].rconst int N=250005,MOD=985003;int read(){    char c=getchar();int x=0,f=1;    while(c<0||c>9){if(c==-)f=-1; c=getchar();}    while(c>=0&&c<=9){x=x*10+c-0; c=getchar();}    return x*f;}int v,tm;char s[15];struct node{    int l,r,v,t,size,rnd;    char s[15];}t[N];int sz,root;inline void update(int x){t[x].size=t[lc].size+t[rc].size+1;}inline void rturn(int &x){    int c=lc;lc=t[c].r;t[c].r=x;    t[c].size=t[x].size;update(x);x=c;}inline void lturn(int &x){    int c=rc;rc=t[c].l;t[c].l=x;    t[c].size=t[x].size;update(x);x=c;}inline void ins(int &x,int v,int tm,char s[]){    if(x==0){        sz++;x=sz;        t[x].l=t[x].r=0;t[x].size=1;        t[x].v=v;t[x].rnd=rand();t[x].t=tm;        memcpy(t[x].s,s,strlen(s));        return;    }    t[x].size++;    if(v<=t[x].v){        ins(lc,v,tm,s);        if(t[lc].rnd<t[x].rnd) rturn(x);    }else{        ins(rc,v,tm,s);        if(t[rc].rnd<t[x].rnd) lturn(x);    }}inline void del(int &x,int v,int tm){    if(x==0) return;    if(t[x].v==v){        if(t[x].t==tm){            if(lc*rc==0) x=lc+rc;            else if(t[lc].rnd<t[rc].rnd) rturn(x),del(x,v,tm);            else lturn(x),del(x,v,tm);        }else{            t[x].size--;            if(tm>t[x].t) del(lc,v,tm);            else del(rc,v,tm);        }    }else{        t[x].size--;        if(v<t[x].v) del(lc,v,tm);        else del(rc,v,tm);    }}int rnk(int x,int v,int tm){    if(x==0) return 0;    if(t[x].v==v){        if(tm==t[x].t) return t[lc].size+1;        else if(tm>t[x].t) return rnk(lc,v,tm);        else return t[lc].size+1+rnk(rc,v,tm);    }    else if(v<t[x].v) return rnk(lc,v,tm);    else return t[lc].size+1+rnk(rc,v,tm);}int kth(int x,int k){    if(x==0) return 0;    if(k<=t[lc].size) return kth(lc,k);    else if(k>t[lc].size+1) return kth(rc,k-t[lc].size-1);    else return x;}struct data{    int v,tm,ne;    char s[15];}mp[MOD+5];int h[MOD+5],cnt;int hsh(char s[]){    int x=0,len=strlen(s+1);    for(int i=1;i<=len;i++) x=(x*27+s[i]-A+1)%MOD;    return x;}inline bool equ(char s1[],char s2[]){    int l1=strlen(s1),l2=strlen(s2);    if(l1!=l2) return false;    for(int i=1;i<=l1;i++) if(s1[i]!=s2[i]) return false;    return true;}void Insert(char s[],int v,int tm){    int k=hsh(s);    for(int i=h[k];i;i=mp[i].ne){        if(equ(s,mp[i].s)){            del(root,mp[i].v,mp[i].tm);            mp[i].v=v;mp[i].tm=tm;            ins(root,v,tm,s);            return;        }    }    cnt++;    mp[cnt].v=v;mp[cnt].tm=tm;    memcpy(mp[cnt].s,s,strlen(s));    mp[cnt].ne=h[k];h[k]=cnt;    ins(root,v,tm,s);}void Rank(char s[]){    int k=hsh(s),i;    for(i=h[k];i;i=mp[i].ne)        if(equ(s,mp[i].s)) break;    printf("%d\n",cnt+1-rnk(root,mp[i].v,mp[i].tm));}void Kth(char s[]){    int k=0,len=strlen(s+1);    for(int i=1;i<=len;i++) k=k*10+s[i]-0;    //printf("Kth %d %s %d\n",k,s,len);    for(int i=k;i<=cnt&&i<=k+9;i++){        printf("%s",t[kth(root,cnt+1-i)].s+1);        if(i<cnt&&i<k+9) putchar( );    }    putchar(\n);}int main(){    int T=read();    for(int i=1;i<=T;i++){        scanf("%s",s);        if(s[0]==+){            v=read();            Insert(s,v,i);        }else{            if(s[1]>=0&&s[1]<=9) Kth(s);            else Rank(s);        }    }}

 

 

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]