zoukankan      html  css  js  c++  java
  • 【bzoj1056】排名系统

    1056: [HAOI2008]排名系统

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2195  Solved: 623
    [Submit][Status][Discuss]

    Description

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

    Input

      第一行是一个整数n(n>=10)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下: +Na
    me Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正
    整数。 ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。 ?Index 返回自第Index名开始的最多10名
    玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。

    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
    4

    HINT

    N<=250000

     
     
    【题解】
    平衡树+哈希
    将名字存在哈希表中,每次新插入一条信息就现在哈希表中找看之前有没有记录,如果有就删除,然后插入。
    但是有个问题,如果你要删的值和结点值相同但是姓名不同,你怎么知道要删左子树还是右子树??
    于是结点还要记录下每个记录时间,删除时只要时间和值相同就行了。
    接下来就是平衡树的基本操作了。
     
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<cmath>
      5 #include<cstdlib>
      6 #include<ctime>
      7 #include<algorithm>
      8 using namespace std;
      9 const int INF=985003;
     10 int n,root,tot,len,head[INF+10];
     11 struct node1{int v,next,time;char ch[10];}hash[250010];
     12 struct node2{int v,time,fix,size,l,r;  char ch[10];}tr[250010];
     13 void updata(int p) {tr[p].size=tr[tr[p].l].size+tr[tr[p].r].size+1;}
     14 void lturn(int &p) {int c=tr[p].r; tr[p].r=tr[c].l; tr[c].l=p; tr[c].size=tr[p].size; updata(p); p=c;}
     15 void rturn(int &p) {int c=tr[p].l; tr[p].l=tr[c].r; tr[c].r=p; tr[c].size=tr[p].size; updata(p); p=c;}
     16 bool cmp(char a[],char b[]) {for(int i=1;i<max(strlen(a),strlen(b));i++) if(a[i]!=b[i]) return 0;return 1;}
     17 int Hash(char ch[]) {int s=0; for(int i=1;i<strlen(ch);i++) {s*=27; s+=ch[i]-'A'+1; s%=INF;} return s;}
     18 void insert(int &p,int v,int time,char ch[])
     19 {
     20     if(!p)
     21     {
     22         p=++len; tr[p].size=1; tr[p].v=v; tr[p].time=time; tr[p].fix=rand();
     23         memcpy(tr[p].ch,ch,strlen(ch)); return;
     24     }
     25     tr[p].size++;
     26     if(v<=tr[p].v)  {insert(tr[p].l,v,time,ch);  if(tr[p].fix>tr[tr[p].l].fix)  rturn(p);}
     27     else {insert(tr[p].r,v,time,ch);  if(tr[p].fix>tr[tr[p].r].fix) lturn(p);}
     28 }
     29 void del(int &p,int v,int time)
     30 {
     31     if(v==tr[p].v)
     32     {
     33         if(time==tr[p].time) 
     34         {
     35             if(tr[p].l*tr[p].r==0)  p=tr[p].l+tr[p].r;
     36             else if(tr[tr[p].l].fix<tr[tr[p].r].fix)  {rturn(p);  del(p,v,time);}
     37             else {lturn(p);  del(p,v,time);}
     38         }
     39         else if(time>tr[p].time)  {tr[p].size--; del(tr[p].l,v,time);}
     40         else {tr[p].size--; del(tr[p].r,v,time);}
     41     }
     42     else if(v<tr[p].v)  {tr[p].size--;  del(tr[p].l,v,time);}
     43     else {tr[p].size--;  del(tr[p].r,v,time);}
     44 }
     45 void work(char ch[],int x,int time)
     46 {
     47     int k=Hash(ch);  int i=head[k];
     48     while(i)
     49     {
     50         if(cmp(hash[i].ch,ch))
     51         {
     52             del(root,hash[i].v,hash[i].time);
     53             hash[i].time=time;  hash[i].v=x;
     54             insert(root,x,time,ch);
     55             return;
     56         }
     57         i=hash[i].next;
     58     }
     59     tot++;
     60     hash[tot].time=time;  hash[tot].v=x;
     61     hash[tot].next=head[k];  head[k]=tot;
     62     memcpy(hash[tot].ch,ch,strlen(ch));
     63     insert(root,x,time,ch);
     64 }
     65 int get(char ch[])
     66 {
     67     int k=Hash(ch);int i=head[k];
     68     while(i)
     69     {
     70         if(cmp(hash[i].ch,ch))return i;
     71         i=hash[i].next;
     72     }
     73 }
     74 int rank(int p,int v,int time)
     75 {
     76     if(p==0)  return 0;
     77     if(tr[p].v==v)
     78     {
     79         if(tr[p].time==time)  return tr[tr[p].r].size+1;
     80         else if(time<tr[p].time)  return rank(tr[p].r,v,time);
     81         else return tr[tr[p].r].size+1+rank(tr[p].l,v,time);
     82     }
     83     else if(v>tr[p].v)  return rank(tr[p].r,v,time);
     84     else return tr[tr[p].r].size+1+rank(tr[p].l,v,time);
     85 }
     86 void ask1(char ch[])
     87 {
     88     int t=get(ch);
     89     printf("%d
    ",rank(root,hash[t].v,hash[t].time));
     90 }
     91 int index(int k,int x)
     92 {
     93     if(tr[tr[k].r].size+1==x)return k;
     94     else if(x<=tr[tr[k].r].size)return index(tr[k].r,x);
     95     else return index(tr[k].l,x-tr[tr[k].r].size-1);
     96 }
     97 void ask2(char ch[])
     98 {
     99     int s=0;
    100     for(int i=1;i<strlen(ch);i++){s*=10;s+=ch[i]-'0';}
    101     for(int i=s;i<=tot&&i<=s+9;i++)
    102     {
    103        printf("%s",tr[index(root,i)].ch+1);
    104        if(i<tot&&i<s+9)printf(" ");
    105     }
    106     printf("
    ");
    107 }
    108 int main()
    109 {
    110     freopen("cin.in","r",stdin);
    111     freopen("cout.out","w",stdout);
    112     scanf("%d",&n);  char ch[11];  int x;
    113     for(int i=1;i<=n;i++)
    114     {
    115         scanf("%s",ch);
    116         if(ch[0]=='+')  {scanf("%d",&x);  work(ch,x,i);}
    117         else if(ch[1]>='A'&&ch[1]<='Z') ask1(ch);
    118         else ask2(ch);
    119     }
    120     return 0;
    121 }
    View Code

     

  • 相关阅读:
    Python学习————作业
    Python学习————前端
    Python学习————前端(JS)
    Python————前端
    Python学习————作业(简单页面设计)
    Python学习————前端(注册)
    Python学习————表格与表单
    Python学习————作业(前端)
    Python学习————前端
    51Nod1307 绳子与重物
  • 原文地址:https://www.cnblogs.com/chty/p/5829408.html
Copyright © 2011-2022 走看看