• bzoj1862: [Zjoi2006]GameZ游戏排名系统


    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
     
     
     
     
    题解:
      好久没有写题了,代码能力都不行了·······注意splay处理区间问题一般要加两个哨兵(烧饼)节点,还有这道题n貌似可以到250000(我也不清楚具体多少,反正200000会挂),更坑爹的是Score可以爆int,坑坑坑
    code:
      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<cassert>
      7 using namespace std;
      8 typedef long long int64;
      9 char ch; bool ok;
     10 void read(int &x){
     11     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     12     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     13     if (ok) x=-x;
     14 }
     15 void read(int64 &x){
     16     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1;
     17     for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar());
     18     if (ok) x=-x;
     19 }
     20 const int maxn=600005;
     21 const int64 inf=9223372036854775807LL;
     22 int q,idx,list[maxn];
     23 int64 x;
     24 char op,tmp[12],name[maxn][12];
     25 struct Hash{
     26     static const int base1=97;
     27     static const int mod1=99997;
     28     static const int base2=103;
     29     static const int mod2=3777777;
     30     int tot,now[mod1],pre[maxn],key[maxn];
     31     void init(){tot=0;memset(now,0,sizeof(now));}
     32     int find(){
     33         int u=0,k=0;
     34         for (int i=1;tmp[i];i++) u=(u*base1+tmp[i])%mod1,k=(k*base2+tmp[i])%mod2;
     35         for (int p=now[u];p;p=pre[p]) if (key[p]==k) return p;
     36         pre[++tot]=now[u],now[u]=tot,key[tot]=k;
     37         for (int i=1;tmp[i];i++) name[tot][i]=tmp[i];
     38         return tot;
     39     }
     40 }data;
     41 struct Splay{
     42     int tot,root,son[maxn][2],fa[maxn],siz[maxn],pos[maxn];
     43     int64 val[maxn];
     44     int which(int x){return son[fa[x]][1]==x;}
     45     void updata(int x){siz[x]=siz[son[x][0]]+1+siz[son[x][1]];}
     46     void rotate(int x){
     47         int y=fa[x],z=fa[y],d=which(x),dd=which(y);
     48         son[y][d]=son[x][d^1],fa[son[x][d^1]]=y,fa[x]=z;
     49         if (z) son[z][dd]=x;
     50         son[x][d^1]=y,fa[y]=x,updata(y),updata(x);    
     51     }
     52     void splay(int x){
     53         while (fa[x]){
     54             if (!fa[fa[x]]) rotate(x);
     55             else if (which(fa[x])==which(x)) rotate(fa[x]),rotate(x);
     56             else rotate(x),rotate(x);
     57         }
     58         root=x;
     59     }
     60     void init(){
     61         memset(siz,0,sizeof(siz)),memset(pos,0,sizeof(pos));
     62         data.init();
     63         root=q+1;
     64         siz[q+1]=2,fa[q+1]=0,son[q+1][0]=0,son[q+1][1]=q+2,val[q+1]=inf;
     65         siz[q+2]=1,fa[q+2]=q+1,son[q+2][0]=son[q+2][1]=0,val[q+2]=-inf;
     66     }
     67     int find_left(int x){
     68         for (;son[x][0];x=son[x][0]);
     69         return x;    
     70     }
     71     void del(int x){
     72         splay(x);
     73         int y=find_left(son[x][1]);
     74         fa[son[x][0]]=fa[son[x][1]]=0;
     75         splay(y),son[y][0]=son[x][0],fa[son[x][0]]=y,updata(y);
     76     }
     77     void insert(int x){
     78         int f,t;
     79         for (f=t=root;t;f=t,t=son[t][val[x]<=val[t]]);
     80         assert(f!=0);
     81         fa[x]=f,son[f][val[x]<=val[f]]=x,splay(x);
     82     }
     83     void push(int64 v){
     84         int id=data.find();
     85         if (pos[id]==0) pos[id]=++tot;
     86         else del(pos[id]);
     87         val[id]=v,siz[id]=1,fa[id]=son[id][0]=son[id][1]=0,insert(pos[id]);
     88     }
     89     int find(int x,int rank){
     90         if (siz[son[x][0]]>=rank) return find(son[x][0],rank);
     91         if (siz[son[x][0]]+1==rank) return x;
     92         return find(son[x][1],rank-siz[son[x][0]]-1);
     93     }
     94     void answer(int x,int rest){
     95         if (rest==0||x==0) return;
     96         answer(son[x][0],rest);
     97         if (siz[son[x][0]]<rest){
     98             list[++idx]=x;
     99             answer(son[x][1],rest-siz[son[x][0]]-1);
    100         }
    101     }
    102     void query_list(int rank){
    103         int id=find(root,rank+1);
    104         splay(id);
    105         list[idx=1]=id;
    106         answer(son[id][1],9);
    107         if (!name[list[idx]][1]) idx--;
    108         for (int i=1;i<idx;i++) printf("%s ",name[list[i]]+1);
    109         printf("%s
    ",name[list[idx]]+1);
    110     }
    111     void query_rank(){
    112         int id=data.find();
    113         splay(id),printf("%d
    ",siz[son[id][0]]);
    114     }
    115 }T;
    116 int main(){
    117     for (read(q),T.init();q;q--){
    118         for (op=getchar();op!='+'&&op!='?';op=getchar());
    119         if (op=='+') scanf("%s",tmp+1),read(x),T.push(x);
    120         else if (op=='?'){
    121             scanf("%s",tmp+1);
    122             if (isdigit(tmp[1])){
    123                 x=0;
    124                 for (int i=1;tmp[i];i++) x=x*10+tmp[i]-'0';
    125                 T.query_list(x);
    126             }
    127             else T.query_rank();
    128         }
    129     }
    130     return 0;
    131 }
  • 相关阅读:
    pycharm中使用redis模块入门
    ubuntu sudo apt-get update与sudo apt-get upgrade的作用及区别,以及python pip的安装
    pycharm修改快捷键
    python2.7.5安装docker-compose的方法
    (二)影响持续交付的因素
    (一)持续交付的定义与价值
    CentOS6的/etc/rc.local不执行的问题解决
    Redis集群进阶之路
    好文收集(长期更新)
    MongoDB如何释放空闲空间?
  • 原文地址:https://www.cnblogs.com/chenyushuo/p/6994936.html
Copyright © 2020-2023  润新知