zoukankan      html  css  js  c++  java
  • 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].r
    const 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
    ",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
    ",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('
    ');
    }
    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);
            }
        }
    }
     
  • 相关阅读:
    纯CSS气泡对话框
    使用JAVASCRIPT实现的 单行文字 逐个文字变色,可以循环控制
    数字转换成中文汉字
    jquery如何在对表格添加删除后再对其前面加上顺序的序列号
    情路
    【缅怀妈妈系列诗歌】之二十四:一份永不忘却的思念
    我等你,千年之后
    赢道在手,前程无忧
    为你感动
    你为什么对我如此冷漠
  • 原文地址:https://www.cnblogs.com/candy99/p/6216455.html
Copyright © 2011-2022 走看看