zoukankan      html  css  js  c++  java
  • 数据结构(Splay平衡树):HAOI2008 排名系统

    [HAOI2008] 排名系统

    [题目描述]

    排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。

    [输入]

    第一行是一个整数n(10<=n<=250000)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下:

    +Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。

    ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。如果两个玩家的得分相同,则先得到该得分的玩家排在前面。

    ?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。

    [输出]

    对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。

    对于?Index格式的请求,应在一行中依次输出从第Index名开始的最多10名玩家姓名,用一个空格分隔。

    [样例]

    Input

    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

    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

    说明

    +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的排名

    [数据范围]

    20%数据满足N<=100

    100%数据满足N<=250000

      数据绝对不是随机的……

      所以每次Insert一定要Splay上去!!!

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <string>
      5 #include <map>
      6 using namespace std;
      7 const int maxn=300010;
      8 const int INF=2147483647;
      9 map<string,int>ID;
     10 char c;
     11 string name[maxn],str;
     12 int rt,cnt,fa[maxn],ch[maxn][2],sz[maxn],key[maxn];
     13 
     14 void Push_up(int x){
     15     sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
     16 }
     17 
     18 void Rotate(int x){
     19     int y=fa[x],g=fa[y],c=ch[y][1]==x;
     20     ch[y][c]=ch[x][c^1];
     21     if(ch[x][c^1])fa[ch[x][c^1]]=y;
     22     ch[x][c^1]=y;fa[y]=x;fa[x]=g;
     23     if(g)ch[g][ch[g][1]==y]=x;
     24     Push_up(y);
     25 }
     26 
     27 void Splay(int x,int g=0){
     28     for(int y;(y=fa[x])!=g;Rotate(x))
     29         if(fa[y]!=g)Rotate((ch[fa[y]][1]==y)==(ch[y][1]==x)?y:x);
     30     Push_up(x);
     31     if(!g)rt=x;
     32 }
     33 
     34 void Get_LR(int x,int &l,int &r){
     35     Splay(x);
     36     l=ch[x][0];r=ch[x][1];
     37     while(ch[l][1])l=ch[l][1];
     38     while(ch[r][0])r=ch[r][0];
     39 }
     40 
     41 void Delete(int x){
     42     int l,r;
     43     Get_LR(x,l,r);
     44     Splay(l);Splay(r,rt);
     45     ch[ch[rt][1]][0]=0;
     46     Push_up(ch[rt][1]);
     47     Push_up(rt);
     48 }
     49 
     50 void Insert(int &p,int f,int id,int x){
     51     if(!p){
     52         key[p=id]=x;
     53         fa[p]=f;
     54         sz[p]=1;
     55         Splay(p);
     56         return;
     57     }
     58     sz[p]+=1;
     59     Insert(ch[p][key[p]<x],p,id,x);
     60 }
     61 
     62 int Get_ID(int k){
     63     int p=rt;
     64     while(true){
     65         if(sz[ch[p][0]]+1==k)break;
     66         if(sz[ch[p][0]]+1>k)p=ch[p][0];
     67         else k-=sz[ch[p][0]]+1,p=ch[p][1];
     68     }
     69     return p;
     70 }
     71 
     72 void Print(int p){
     73     if(!p)return;
     74     Print(ch[p][1]);
     75     cout<<name[p]<<" ";
     76     Print(ch[p][0]);
     77 }
     78 
     79 void Init(){
     80     Insert(rt,0,1,-INF);
     81     Insert(rt,0,2,INF);cnt=2;
     82 }
     83 
     84 int main(){
     85 #ifndef ONLINE_JUDGE
     86     freopen("rank.in","r",stdin);
     87     freopen("rank.out","w",stdout);
     88 #endif
     89     Init();
     90     int Q,d,tot=0;
     91     scanf("%d",&Q);
     92     while(Q--){
     93         do c=getchar();
     94         while(c!='+'&&c!='?');
     95     
     96         if(c=='+'){    
     97             cin>>str;
     98             scanf("%d",&d);
     99             if(ID[str]){
    100                 Delete(ID[str]);
    101                 Insert(rt,0,ID[str],d);
    102             }
    103             else{
    104                 ID[str]=++cnt;tot+=1;name[cnt]=str;
    105                 Insert(rt,0,ID[str],d);
    106             }
    107         }
    108         else{
    109             cin>>str;
    110             if(str[0]<='9'&&str[0]>='0'){
    111                 int l,r=0;
    112                 for(int i=0;str[i];i+=1)
    113                     r=r*10+(str[i]-'0');
    114                 r=tot-r+1;l=max(r-9,1);
    115                 Splay(Get_ID(l));Splay(Get_ID(r+2),rt);
    116                 Print(ch[ch[rt][1]][0]);
    117                 printf("
    ");
    118             }
    119             else{
    120                 Splay(Get_ID(1));Splay(ID[str],rt);
    121                 printf("%d
    ",tot-sz[ch[ch[rt][1]][0]]);
    122             }    
    123         }
    124     }
    125     return 0;
    126 }
    尽最大的努力,做最好的自己!
  • 相关阅读:
    请注意更新TensorFlow 2.0的旧代码
    tf.cast用法
    文件句柄
    Python学习(四)cPickle的用法
    机器都会学习了,你的神经网络还跑不动?来看看这些建议
    Hadoop集群管理之配置文件
    SQL之case when then用法
    关于2014
    Oracle之虚拟索引
    Linux之Ganglia源码安装
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5592097.html
Copyright © 2011-2022 走看看