BZOJ1056/1862: [HAOI2008]排名系统
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
const int N=300005;
char c,name[N][20];
int root,sco[N],n;
map<string,int>has;
int siz[N],rs[N],ls[N],rnd[N],a[N],t[N],cnt;
void Pushup(int x)
{
siz[x]=siz[ls[x]]+siz[rs[x]]+1;
}
void lt(int &x)
{
int t=rs[x];
rs[x]=ls[t],ls[t]=x;
Pushup(x),Pushup(t);
x=t;
}
void rt(int &x)
{
int t=ls[x];
ls[x]=rs[t],rs[t]=x;
Pushup(x),Pushup(t);
x=t;
}
void Ins(int &x,int v,int tim)
{
if(!x)
{
x=++cnt,a[x]=v,t[x]=tim,siz[x]=1,rnd[x]=rand();
return;
}
if(v>a[x])
{
Ins(ls[x],v,tim);
if(rnd[ls[x]]>rnd[x]) rt(x);
}
else
{
Ins(rs[x],v,tim);
if(rnd[rs[x]]>rnd[x]) lt(x);
}
Pushup(x);
}
void Del(int &x,int v,int tim)
{
if(!x) return;
if(v==a[x]&&tim==t[x])
{
if(ls[x]*rs[x]==0) {x=ls[x]+rs[x];return;}
if(rnd[ls[x]]>rnd[rs[x]]) rt(x),Del(x,v,tim);
else lt(x),Del(x,v,tim);
}
else if(v>a[x]||v==a[x]&&tim<t[x]) Del(ls[x],v,tim);
else Del(rs[x],v,tim);
Pushup(x);
}
int Getrank(int x,int v,int tim)
{
if(v==a[x]&&tim==t[x]) return siz[ls[x]]+1;
if(v>a[x]||v==a[x]&&tim<t[x]) return Getrank(ls[x],v,tim);
else return Getrank(rs[x],v,tim)+siz[ls[x]]+1;
}
int tar;
int Getname(int x,int rank)
{
if(rank==siz[ls[x]]+1) return t[x];
else if(rank<=siz[ls[x]]) return Getname(ls[x],rank);
else return Getname(rs[x],rank-siz[ls[x]]-1);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("\n%c",&c);
scanf(" %s",name[i]);
int len=strlen(name[i]),tmp,x;
if(c=='+')
{
scanf("%d",&x);
tmp=has[name[i]];
if(tmp) Del(root,sco[tmp],tmp);
Ins(root,x,i);
has[name[i]]=i;
sco[i]=x;
}
else if(c=='?')
{
if(name[i][0]<='9'&&name[i][0]>='0')
{
x=0;
for(int j=0;j<len;j++)
x=x*10+name[i][j]-'0';
int mx=min(siz[root],x+9);
for(int j=x;j<mx;j++)
printf("%s ",name[Getname(root,j)]);
printf("%s\n",name[Getname(root,mx)]);
}
else
{
tmp=has[name[i]];
printf("%d\n",Getrank(root,sco[tmp],tmp));
}
}
}
}
Description
Input
Output
Sample Input
+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
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