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