排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。
排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。
第一行是一个整数n(n>=10)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下: +Name Score 上传最新得分记录。Name表示玩家名字,由大写英文字母组成,不超过10个字符。Score为最多8位的正整数。 ?Name 查询玩家排名。该玩家的得分记录必定已经在前面上传。 ?Index 返回自第Index名开始的最多10名玩家名字。Index必定合法,即不小于1,也不大于当前有记录的玩家总数。
对于?Name格式的请求,应输出一个整数表示该玩家当前的排名。对于?Index格式的请求,应在一行中依次输出从第Index名开始的最多10名玩家姓名,用一个空格分隔。
100%数据满足N<=250000
显然题目要你维护一颗排名树。。
把每个人的名字转换成27进制然后treap瞎搞一通。。。
为什么27进制呢。。。
因为离散化后想用1~26来表示,如果用26进制0~25里面的0(A)不好判断。。。
<strong><span style="font-size:18px;">#include<iostream> #include<cstdio> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; const int maxn = 250000+10; typedef long long LL; int n,i,j,S[maxn],t[maxn],cur = 0,New,tail = 0,TOT = 0,END; LL sorta[maxn]; bool vis[maxn]; struct Q{ char flag,nam[15]; int sco; }query[maxn]; class data{ private: struct Node{ int pri,siz,num,sco; Node *ch[2]; }*root,*tot,pool[maxn]; void maintain(Node *&x) { x->siz = 1; for (int l = 0; l <= 1; l++) if (x->ch[l] != NULL) x->siz += x->ch[l]->siz; } void rotate(Node *&x,int d) { Node *y = x->ch[d]; x->ch[d] = y->ch[d^1]; maintain(x); y->ch[d^1] = x; x = y; maintain(x); } int cmp(Node *x,int Num) { if (x->sco < S[Num]) return 0; if (x->sco > S[Num]) return 1; if (t[x->num] < t[Num]) return 1; return 0; } void Insert(Node *&x,int sco,int pri,int num) { if (x == NULL) { x = tot++; x->sco = sco; x->pri = pri; x->num = num; x->ch[0] = NULL; x->ch[1] = NULL; x->siz = 1; return; } int d = cmp(x,num); Insert(x->ch[d],sco,pri,num); maintain(x); if (x->ch[d]->pri > x->pri) rotate(x,d); } void Remove(Node *&x,int num) { if (x->num == num) { if (x->ch[0] == NULL && x->ch[1] == NULL) { x = NULL; return; } for (int l = 0; l <= 1; l++) if (x->ch[l] == NULL) { x = x->ch[l^1]; return; } int d1 = x->ch[0]->pri > x->ch[1]->pri?0:1; rotate(x,d1); Remove(x->ch[d1^1],num); if (x != NULL) maintain(x); return; } int d = cmp(x,num); Remove(x->ch[d],num); if (x != NULL) maintain(x); } int Lower_Bound(Node *x,int Num) { for (;;) { int d = 1; if (x->ch[0] != NULL) d += x->ch[0]->siz; if (d == Num) return x->num; if (d > Num) x = x->ch[0]; else { Num -= d; x = x->ch[1]; } } } int find_rank(Node *x,int num) { int ret = 0; for (;;) { int d = cmp(x,num); if (x->num == num) { if (x->ch[0] != NULL) ret += x->ch[0]->siz; return ret+1; } if (d) { ++ret; if (x->ch[0] != NULL) ret += x->ch[0]->siz; x = x->ch[1]; } else x = x->ch[0]; } } public: data(){root = NULL; tot = pool;} void Ins(int num,int sco) { Insert(root,sco,rand(),num); } void Rem(int num) { Remove(root,num); } int L_B(int num) { return Lower_Bound(root,num); } int F_R(int num) { return find_rank(root,num); } }; char get_com() { char ret = 0; while (ret != '+' && ret != '?') ret = getchar(); return ret; } LL get_num(int pos) { LL ret = 0,x = 1; int len = strlen(query[pos].nam); for (int l = 0; l < len; l++) { ret = ret + 1LL*(query[pos].nam[l]-'A'+1)*x; x *= 27; } return ret; } void pri(int pos) { LL out = sorta[pos]; for (; out; out /= 27LL) printf("%c",out%27LL+'A'-1); if (i != END) printf(" "); } int main() { #ifdef YZY freopen("yzy.txt","r",stdin); #endif cin >> n; static data tree; tree.Ins(0,-2E9); for (i = 0; i < n; i++) { query[i].flag = get_com(); scanf("%s",&query[i].nam); if (query[i].flag == '+') { int sco; scanf("%d",&query[i].sco); sorta[++TOT] = get_num(i); } } sort(sorta+1,sorta+TOT+1); j = TOT; TOT = 1; for (i = 2; i <= j; i++) if (sorta[i] != sorta[i-1]) sorta[++TOT] = sorta[i]; for (j = 0; j < n; j++) { if (query[j].flag == '+') { LL N = get_num(j); int num = lower_bound(sorta + 1,sorta + TOT + 1,N) - sorta; if (vis[num]) tree.Rem(num); if (!vis[num]) vis[num] = 1,++cur; S[num] = query[j].sco; t[num] = j; tree.Ins(num,query[j].sco); } else { if (query[j].nam[0] >= '0' && query[j].nam[0] <= '9') { int num = 0,len = strlen(query[j].nam); for (i = 0; i < len; i++) num = num*10 + query[j].nam[i]-'0'; END = num+9<=cur?num+9:cur; for (i = num; i <= END; i++) pri(tree.L_B(i)); printf("\n"); } else { LL num = get_num(j); int N = lower_bound(sorta + 1,sorta + TOT + 1,num) - sorta; printf("%d\n",tree.F_R(N)); } } } return 0; }</span></strong>