GameZ游戏排名系统

时间:2019-11-27
本文章向大家介绍GameZ游戏排名系统 ,主要包括GameZ游戏排名系统 使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

GameZ游戏排名系统

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

思路:

\(FHQ\_treap\ or\ splay\)维护得分对应的名字\(\And\)用另一个平衡树维护名字\(hash\)后对应的得分\(,\)输出时区间提取。(如果单次查询找\(10\)次排名可能会\(TLE\)

当然,为了区分得分相同但名字不同的可以使用时间戳\(or\)随机数

\(\mathfrak{Talk\ is\ cheap,show\ you\ the\ code.}\)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
# define Type template<typename T>
# define read read1<int>()
Type inline T read1()
{
    T t=0;
    bool ty=0;
    char k;
    do k=getchar(),(k=='-')&&(ty=1);while('0'>k||k>'9');
    do t=(t<<3)+(t<<1)+(k^'0'),k=getchar();while('0'<=k&&k<='9');
    return ty?-t:t;
}
# define fre(k) freopen(k".in","r",stdin);freopen(k".out","w",stdout)
template<typename T>
    class FHQ_treap
    {
        private:
            int seed;
        public:
            int Rand(){return seed=seed*33457+52331314;}
            class node
            {
                public:
                    node *l,*r;
                    T k;
                    int cnt,si,q;
                    node(){l=r=NULL;cnt=si=1;}
                    node(T k1,int q1){l=r=NULL;cnt=si=1;k=k1;q=q1;}
            }*root;
            class Pair
            {
                public:
                    node *l,*r;
                    Pair(){}
                    Pair(node *a,node *b){l=a;r=b;}
            };
        private:
            void pushup(node *n){n->si=size(n->l)+size(n->r)+n->cnt;}
            int size(node *n){return n?n->si:0;}
            Pair _split(node *n,T v)
            {
                if(!n)return Pair(NULL,NULL);
                Pair tem;
                if(v<n->k)
                {
                    tem=_split(n->l,v);
                    n->l=tem.r;
                    tem.r=n;
                }
                else
                {
                    tem=_split(n->r,v);
                    n->r=tem.l;
                    tem.l=n;
                }
                pushup(n);
                return tem;
            }
            Pair split_(node *n,T v)
            {
                if(!n)return Pair(NULL,NULL);
                Pair tem;
                if(v<=n->k)
                {
                    tem=split_(n->l,v);
                    n->l=tem.r;
                    tem.r=n;
                }
                else
                {
                    tem=split_(n->r,v);
                    n->r=tem.l;
                    tem.l=n;
                }
                pushup(n);
                return tem;
            }
            node* merge(node *l,node *r)
            {
                if(!l or !r)return l?l:r;
                node* re;
                if(l->q<r->q)l->r=merge(l->r,r),re=l;
                else r->l=merge(l,r->l),re=r;
                pushup(re);
                return re;
            }
            node* findmin(node* n){while(n->l)n=n->l;return n;}
            node* findmax(node* n){while(n->r)n=n->r;return n;}
        public:
            FHQ_treap(){root=NULL;seed=4088;}
            void insert(T ke)
            {
                Pair tem=_split(root,ke),tem1=split_(tem.l,ke);
                if(tem1.r)++tem1.r->cnt,++tem1.r->si;
                else tem1.r=new node(ke,Rand());
                root=merge(merge(tem1.l,tem1.r),tem.r);
            }
            void del(T ke)
            {
                Pair tem=_split(root,ke),tem1=split_(tem.l,ke);
                if(tem1.r and --tem1.r->cnt)--tem1.r->si,tem1.l=merge(tem1.l,tem1.r);
                root=merge(tem1.l,tem.r);
            }
            T upper(T ke)
            {
                Pair tem=_split(root,ke);
                T tans=findmin(tem.r)->k;
                merge(tem.l,tem.r);
                return tans;
            }
            T lower(T ke)
            {
                Pair tem=split_(root,ke);
                T tans=findmax(tem.l)->k;
                merge(tem.l,tem.r);
                return tans;
            }
            int findrank(T ke)
            {
                Pair tem=split_(root,ke);
                int tans=size(tem.l)+1;
                merge(tem.l,tem.r);
                return tans;
            }
            T findwho(int n)
            {
                for(node* i=root;i;)
                    if(n<=size(i->l))i=i->l;
                    else if(size(i->l)+i->cnt<n)n-=size(i->l)+i->cnt,i=i->r;
                    else return i->k;
                return 0;
            }
    };
template<typename T,typename _T>
    class FHQ_treap_map
    {
        private:
            int seed,space;
        public:
            int Rand(){return seed=seed*33457+52331314;}
            class node
            {
                public:
                    node *l,*r;
                    T k;_T v;
                    int cnt,si,q;
                    node(){l=r=NULL;cnt=si=1;}
                    node(T k1,_T v1,int q1){l=r=NULL;cnt=si=1;k=k1;v=v1;q=q1;}
            }*root;
            class Pair
            {
                public:
                    node *l,*r;
                    Pair(){}
                    Pair(node *a,node *b){l=a;r=b;}
            };
        private:
            void pushup(node *n){n->si=size(n->l)+size(n->r)+n->cnt;}
            int size(node *n){return n?n->si:0;}
            Pair split(node *n,int ra)
            {
                if(!n)return Pair(NULL,NULL);
                Pair tem;
                if(ra<=size(n->l))
                {
                    tem=split(n->l,ra);
                    n->l=tem.r;
                    tem.r=n;
                }
                else
                {
                    tem=split(n->r,ra-size(n->l)-n->cnt);
                    n->r=tem.l;
                    tem.l=n;
                }
                pushup(n);
                return tem;
            }
            Pair _split(node *n,T v)
            {
                if(!n)return Pair(NULL,NULL);
                Pair tem;
                if(v<n->k)
                {
                    tem=_split(n->l,v);
                    n->l=tem.r;
                    tem.r=n;
                }
                else
                {
                    tem=_split(n->r,v);
                    n->r=tem.l;
                    tem.l=n;
                }
                pushup(n);
                return tem;
            }
            Pair split_(node *n,T v)
            {
                if(!n)return Pair(NULL,NULL);
                Pair tem;
                if(v<=n->k)
                {
                    tem=split_(n->l,v);
                    n->l=tem.r;
                    tem.r=n;
                }
                else
                {
                    tem=split_(n->r,v);
                    n->r=tem.l;
                    tem.l=n;
                }
                pushup(n);
                return tem;
            }
            node* merge(node *l,node *r)
            {
                if(!l or !r)return l?l:r;
                node* re;
                if(l->q<r->q)l->r=merge(l->r,r),re=l;
                else r->l=merge(l,r->l),re=r;
                pushup(re);
                return re;
            }
            node* findmin(node* n){while(n->l)n=n->l;return n;}
            node* findmax(node* n){while(n->r)n=n->r;return n;}
        public:
            FHQ_treap_map(){root=NULL;seed=4088;}
            void insert(T ke,_T va)
            {
                ++space;
                Pair tem=_split(root,ke);
                root=merge(merge(tem.l,new node(ke,va,Rand())),tem.r);
            }
            void del(T ke)
            {
                --space;
                Pair tem=_split(root,ke),tem1=split_(tem.l,ke);
                root=merge(tem1.l,tem.r);
            }
            T upper(T ke)
            {
                Pair tem=_split(root,ke);
                T tans=findmin(tem.r)->k;
                merge(tem.l,tem.r);
                return tans;
            }
            T lower(T ke)
            {
                Pair tem=split_(root,ke);
                T tans=findmax(tem.l)->k;
                merge(tem.l,tem.r);
                return tans;
            }
            int findrank(T ke)
            {
                Pair tem=split_(root,ke);
                int tans=size(tem.l)+1;
                merge(tem.l,tem.r);
                return tans;
            }
            T findwho(int n)
            {
                for(node* i=root;i;)
                    if(n<=size(i->l))i=i->l;
                    else if(size(i->l)+i->cnt<n)n-=size(i->l)+i->cnt,i=i->r;
                    else return i->k;
                return 0;
            }
            bool find(T n)
            {
                for(node* i=root;i;)
                    if(i->k==n)return 1;
                    else if(i->k>n)i=i->l;
                    else i=i->r;
                return 0;
            }
            _T operator [] (const T n)
            {
                for(node* i=root;i;)
                    if(i->k==n)return i->v;
                    else if(i->k>n)i=i->l;
                    else i=i->r;
                return root->v;
            }
            void pr(node* n,void (*w)(_T) )
            {
                if(!n)return;
                pr(n->l,w);
                w(n->v);putchar(' ');
                pr(n->r,w);
            }
            void query(int l,int r,void (*w)(_T) )
            {
                if(r>space)r=space;
                Pair tem=split(root,l-1),tem1=split(tem.r,r-l+1);
                pr(tem1.l,w);
                merge(tem.l,merge(tem1.l,tem1.r));
            }
    };
# define ull unsigned long long
# define A pair<int,int> 
FHQ_treap_map<A,ull>tr;
char str[11];
FHQ_treap_map<ull,A>ma;
ull Hash(char* str)
{
    ull t=0;
    while(*str)t=t*27ull+*str-'A'+1,++str;
    return t;
}
void print(ull k)
{
    if(!k)return;
    print(k/27ull);
    putchar('A'+k%27ull-1);
}
int main()
{
    //fre("1");
    int D=0;
    for(int T=read;T--;)
    {
        scanf("%s",str);
        ull has,te;
        if(*str=='+')
        {
            has=Hash(str+1);
            if(ma.find(has))tr.del(ma[has]),ma.del(has);
            ma.insert(has,A(te=-read,++D));
            tr.insert(A(te,D),has);
        }
        else if(*str=='?')
            if(*(str+1)<'A')
            {
                int ke;
                sscanf(str+1,"%d",&ke);
                tr.query(ke,ke+9,print);
                putchar('\n');
            }
            else if(ma.find(has=Hash(str+1)))
                    printf("%d\n",tr.findrank(ma[has]));
    }
    return 0;
}
/*
20
+ADAM 1000000
+BOB 1000000
+TOM 2000000
+CATHY 10000000
?TOM
?1
+DAM 100000
+BOB 1200000
+ADAM 900000
+FRANK 12340000
+LEO 9000000
+KAINE 9000000
+GRACE 8000000
+WALT 9000000
+SANDY 8000000
+MICK 9000000
+JACK 7320000
?2
?5
?KAINE

*/

原文地址:https://www.cnblogs.com/SYDevil/p/11943754.html