【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\n", 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 ("\n");
171             }
172         }
173     }
174 }
时间: 2024-10-11 12:56:02

【BZOJ 1056 1862】排名系统的相关文章

bzoj 1862/1056 [HAOI2008]排名系统

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1862 很恶心的 一道题,我也不晓得自己是第几次写这题了%>_<%. 写了两种方法,平衡树+哈希和平衡树+map.哈希函数是抄别人的.比较了一下还是哈希快一些. 题意很简单,就不说了. 具体思路是,平衡树维护排名,map建立姓名和分数一一对应的关系. 求rank时题意默认是越先提交得分排名越靠前(相同得分的条件下). 具体如下: 平衡树+map 1 #include<algorit

HNOI2008 and ZJOI2006 排名系统

1056: [HAOI2008]排名系统 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1311  Solved: 337[Submit][Status] Description 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. Input 第一行是一个整数n(n

BZOJ 1862/1056 ZJOI 2006 GameZ游戏排名系统/ HAOI 2008 排名系统 Treap (双倍经验)

题目大意:维护一种游戏排名系统,为他们的得分排序,若得分一样,则时间早的优先.有的时候要查询一个人是第几名,或者一段名次都是谁. 思路:拿到题一看就知道是暴力Treap乱搞,但是一查不知道看到了谁的文章,说Treap会T,我就战战兢兢的写了Splay,结果T了,拿到数据发现被一个点卡了100s.于是怒写Treap,1.2s怒切. PS:千万不要相信谣言.. CODE: #include <cstdio> #include <cctype> #include <cstring&

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 Splay

Splay的基本操作,比较繁琐..... 有个一坑点,sorce会超int 1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 913  Solved: 343 [Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家

BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][Status][Discuss] Description GameZ为他们最新推出的游戏开通了一个网站.世界各地的玩家都可以将自己的游戏得分上传到网站上.这样就可以看到自己在世界上的排名.得分越高,排名就越靠前.当两个玩家的名次相同时,先上传记录者优先.由于新游戏的火爆,网站服务器已经难堪重负.为此

splay专题复习——bzoj 3224 &amp; 1862 &amp; 1503 题解

[前言]快要省选二试了.上次去被虐出翔了~~这次即便是打酱油,也要打出风采!于是暂停新东西的学习,然后开始复习以前的知识,为骗分做准备.PS:区间翻转的暂时跳过,就算学了也来不及巩固了. [BZOJ3224] 3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1477  Solved: 570 Description 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 1. 插入

数据结构(Splay平衡树):HAOI2008 排名系统

[HAOI2008] 排名系统 [题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入] 第一行是一个整数n(10<=n<=250000)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超

【HAOI2008】排名系统

[题目描述] 排名系统通常要应付三种请求:上传一条新的得分记录.查询某个玩家的当前排名以及返回某个区段内的排名记录.当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除.为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录. [输入格式] 第一行是一个整数n(n>=10)表示请求总数目.接下来n行,每行包含了一个请求.请求的具体格式如下: +Name Score 上传最新得分记录.Name表示玩家名字,由大写英文字母组成,不超过10个字符.Score为最多8位的正整数.

[COGS257]动态排名系统 树状数组套主席树

257. 动态排名系统 时间限制:5 s   内存限制:512 MB [问题描述]给定一个长度为N的已知序列A[i](1<=i<=N),要求维护这个序列,能够支持以下两种操作:1.查询A[i],A[i+1],A[i+2],...,A[j](1<=i<=j<=N)中,升序排列后排名第k的数.2.修改A[i]的值为j.所谓排名第k,指一些数按照升序排列后,第k位的数.例如序列{6,1,9,6,6},排名第3的数是6,排名第5的数是9.[输入格式]第一行包含一个整数D(0<=