zoukankan      html  css  js  c++  java
  • 【BZOJ 1056 1862】排名系统

    Description

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

    Input

    第一行是一个整数n(n>=10)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下: +Name 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

    100%数据满足N<=250000

    分析:

      HASH表加上平衡树,这里的平衡树需要支持Insert(添加)、Delete(删除)、Rank(查询元素在树中的排名)和Select(找出第k大)。

      需要注意的是,如果两个玩家的得分相同,则比较最后一次更新的时间,而不是加入玩家的时间。

      这里用的是SBT。

      1 //
      2 // When I first coded it
      3 // Just God and I could understand it
      4 // But now
      5 // Just God could
      6 // 
      7 
      8 #include <cstdio>
      9 #include <cstring>
     10 
     11 #define HASHMOD 318931
     12 #define MAXN 318931
     13 
     14 int n, sco, len;
     15 int prev[HASHMOD], last[HASHMOD];
     16 int score[HASHMOD], older[HASHMOD], num, old;
     17 int father[MAXN], child[MAXN][2];
     18 int point[MAXN], size[MAXN], cnt, root;
     19 char str[15], hash_value[HASHMOD][15];
     20 
     21 inline int Hash_Insert (int hash, int value)
     22 {
     23     num++;
     24     prev[num] = last[hash];
     25     last[hash] = num;
     26     score[num] = value;
     27     older[num] = ++old;
     28     strcpy (hash_value[num], str);
     29     return num;
     30 }
     31 
     32 inline int Hash_Find (int hash)
     33 {
     34     for (int i = last[hash]; i; i = prev[i])
     35         if (strcmp (hash_value[i], str) == 0)
     36             return i;
     37     return -1;
     38 }
     39 
     40 void Rotate (int& f, int d)
     41 {
     42     int c = child[f][!d];
     43     child[f][!d] = child[c][d];
     44     child[c][d] = f;
     45     size[c] = size[f];
     46     size[f] = size[child[f][0]] + size[child[f][1]] + 1;
     47     f = c;
     48 }
     49 
     50 int NewNode (int p)
     51 {
     52     cnt++;
     53     point[cnt] = p;
     54     size[cnt] = 1;
     55     return cnt;
     56 }
     57 
     58 void MainTain (int& t, int d)
     59 {
     60     if (!t) return;
     61     if (size[child[child[t][d]][d]] > size[child[t][!d]])
     62         Rotate (t, !d);
     63     else if (size[child[child[t][d]][!d]] > size[child[t][!d]])
     64         Rotate (child[t][d], d), Rotate (t, !d);
     65     else return;
     66     MainTain (child[t][0], 0);
     67     MainTain (child[t][1], 1);
     68     MainTain (t, 0);
     69     MainTain (t, 1);
     70 }
     71 
     72 inline bool Cmp (int p, int t)
     73 {
     74     bool ret = score[p] < score[point[t]];
     75     if (score[p] == score[point[t]]) ret = older[p] >= older[point[t]];
     76     return ret;
     77 }
     78 
     79 void Insert (int& t, int p)
     80 {
     81     if (t == 0) t = NewNode (p);
     82     else
     83     {
     84         size[t]++;
     85         int d = Cmp (p, t);
     86         Insert (child[t][d], p);
     87         MainTain (t, d);
     88     }
     89 }
     90 
     91 int Delete (int& t, int p)
     92 {
     93     int Ret;
     94     size[t]--;
     95     int d = Cmp (p, t);
     96     if (p == point[t] || child[t][d] == 0)
     97     {
     98         Ret = point[t];
     99         if (child[t][0] && child[t][1])
    100             point[t] = Delete (child[t][0], p);
    101         else t = child[t][0] + child[t][1];
    102     } else Ret = Delete (child[t][d], p);
    103     return Ret;
    104 }
    105 
    106 void DelBoot (int p)
    107 {
    108     int i = Delete (root, p);
    109     if (i != p) Insert (root, i);
    110 }
    111 
    112 inline void modify (int hash)
    113 {
    114     int id = Hash_Find (hash);
    115     if (id < 0) id = Hash_Insert (hash, sco);
    116     else DelBoot (id), score[id] = sco, older[id] = ++old;
    117     Insert (root, id);
    118 }
    119 
    120 int Rank (int t, int p)
    121 {
    122     if (t == 0) return -1;
    123     if (point[t] == p) return size[child[t][0]] + 1;
    124     int d = Cmp (p, t);
    125     if (d) return Rank (child[t][1], p) + size[child[t][0]] + 1;
    126     return Rank (child[t][0], p);
    127 }
    128 
    129 int Select (int t, int k)
    130 {
    131     if (t == 0) return -1;
    132     if (size[child[t][0]] == k - 1) return point[t];
    133     if (size[child[t][0]] > k - 1) return Select (child[t][0], k);
    134     return Select (child[t][1], k - size[child[t][0]] - 1);
    135 }
    136 
    137 int main ()
    138 {
    139     scanf ("%d", &n);
    140     for (int i = 0; i < n; i++)
    141     {
    142         scanf ("%s", str);
    143         len = strlen (str);
    144         int hash = 0, a = 3785, b = 639;
    145         for (int j = 1; j < len; j++)
    146         {
    147             hash = ((long long) hash * a + (str[j] == '?' ? '+' : str[j])) % HASHMOD;
    148             a = a * b % HASHMOD;
    149         }
    150         if (str[0] == '+')
    151         {
    152             scanf ("%d", &sco);
    153             modify (hash);
    154         } else if (str[0] == '?')
    155         {
    156             if (str[1] > '9')
    157             {
    158                 str[0] = '+';
    159                 printf ("%d
    ", Rank (root, Hash_Find (hash)));
    160             } else
    161             {
    162                 sco = 0;
    163                 for (int j = 1; j < len; j++)
    164                     sco = sco * 10 + str[j] - '0';
    165                 for (int j = 0; j < 10 && sco <= size[root]; j++, sco++)
    166                 {
    167                     if (j > 0) printf (" ");
    168                     printf ("%s", hash_value[Select (root, sco)] + 1);
    169                 }
    170                 printf ("
    ");
    171             }
    172         }
    173     }
    174 }
  • 相关阅读:
    10个有用的网站访问分析工具
    在 IIS6 ASP.NET 4.0 安装 最常遇到的四个问题
    [转]qUIpt:JavaScript Cache Library
    Windows Phone 7 Jump Start
    TFS GrantBackup Plan Permissions Error
    JQuery 专题
    IEnumberable<String> To String
    Charts Controls 开发系列2
    Script#
    SQL SERVER 经验、资料收录
  • 原文地址:https://www.cnblogs.com/lightning34/p/4461022.html
Copyright © 2011-2022 走看看