http://www.elijahqi.win/archives/3041
Description
排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名
记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区
段内的排名记录时,最多返回10条记录。
Input
第一行是一个整数n(n>=10)表示请求总数目。接下来n行,每行包含了一个请求。请求的具体格式如下: +Na
me 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
N<=250000
Source
不知道为什么突然就bzoj rk2了 写了写这码农题..
注意输入是有long long的 然后剩下这个文本就hash一下记下编号就行 然后每次传递进去把这个编号插入splay即可 注意hash表大小..最近写了bsgs一直开1e5 然后这个就炸了 菜… 其他细节代码见qwq
#include<cstdio>
#include<cctype>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 1LL<<60
#define ugint unsigned int
using namespace std;
inline char gc(){
static char now[1<<16],*S,*T;
if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
return *S++;
}
inline ll read(){
ll x=0,f=1;char ch=gc();
while(!isdigit(ch)) {if (ch=='-') f=-1;ch=gc();}
while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
return x*f;
}
const int out_len=1<<16;
char obuf[out_len],*oh=obuf;
inline void write_char(char c){
if (oh==obuf+out_len) fwrite(obuf,1,out_len,stdout),oh=obuf;
*oh++=c;
}
template<class T>
inline void W(T x){
static int buf[30],cnt;
if (!x) write_char('0');else{
if (x<0) write_char('-'),x=-x;
for (cnt=0;x;x/=10) buf[++cnt]=x%10+48;
while(cnt) write_char(buf[cnt--]);
}
}
inline void flush(){fwrite(obuf,1,oh-obuf,stdout);}
const int N=300050;
const int mod=1e6+7;
struct node{
ugint x;int id,next;
}hs[mod];int h[mod],num,cnt,root;
inline int query(ugint x){
static int tmp;tmp=x%mod;
for (int i=h[tmp];i;i=hs[i].next){
if(hs[i].x==x) return hs[i].id;
}hs[++num]=(node){x,++cnt,h[tmp]};h[tmp]=num;return cnt;
}
char s[20],name[N][20];int id;bool flag[N];
int c[N][2],fa[N],size[N];ll v[N];
inline void show(int x){
if (c[x][0]) show(c[x][0]);
for (int i=1;i<=name[x][0];++i) write_char(name[x][i]);write_char(' ');
if (c[x][1]) show(c[x][1]);
}
inline void update(int x){
size[x]=size[c[x][0]]+size[c[x][1]]+1;
}
inline void rotate(int x,int &tar){
int y=fa[x],z=fa[y],l=c[y][1]==x,r=l^1;
if (y==tar) tar=x;else c[z][c[z][1]==y]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;update(y);update(x);
}
inline void splay(int x,int &tar){
while(x!=tar){
int y=fa[x],z=fa[y];
if (y!=tar){
if (y==c[z][0]^x==c[y][0]) rotate(x,tar);else rotate(y,tar);
}rotate(x,tar);
}
}
inline int find(int x,int k){
int l=c[x][0],r=c[x][1];
if (size[l]+1==k) return x;
if (k<=size[l]) return find(l,k);else return find(r,k-size[l]-1);
}
inline int split(int x,int y){
int xx=find(root,x),yy=find(root,y);
splay(yy,root);splay(xx,c[yy][0]);return c[xx][1];
}
inline void print(int x){
if (c[x][0]) print(c[x][0]);
printf("%d %s\n",v[x],name[x]+1);
if (c[x][1]) print(c[x][1]);
}
inline int read_s(){static ugint Hs;static int len;
static char ch;ch=gc();while(ch!='+'&&ch!='?') ch=gc();
if (ch=='+'){len=0;Hs=0;ch=gc();
while(ch<='Z'&&ch>='A') s[++len]=ch,Hs+=Hs*27+s[len]-'A'+1,ch=gc();
s[len+1]='\0';id=query(Hs);if (!flag[id]) memcpy(name[id],s,sizeof(s));
name[id][0]=len;return 0;
}ch=gc();
if (isdigit(ch)){
int x=0;while(isdigit(ch)) x=x*10+ch-'0',ch=gc();
int tmp=split(x,min(cnt,x+11));//print(tmp);
show(tmp);write_char('\n');return 2;
}len=0;Hs=0;
while(ch<='Z'&&ch>='A') s[++len]=ch,Hs+=Hs*27+s[len]-'A'+1,ch=gc();
s[len+1]='\0';id=query(Hs);return 1;
}
inline void insert1(int &x,ll vv,int f){
if (!x) {x=id;size[id]=1;v[id]=vv;fa[id]=f;splay(id,root);return;}
if (vv>v[x]) insert1(c[x][0],vv,x);else insert1(c[x][1],vv,x);
}
inline void del(){
splay(id,root);int pre=c[id][0],succ=c[id][1];
while(c[pre][1]) pre=c[pre][1];while(c[succ][0]) succ=c[succ][0];
splay(succ,root);splay(pre,c[root][0]);
c[pre][1]=fa[c[pre][1]]=0;update(pre);update(succ);
}
int main(){
freopen("bzoj1056.in","r",stdin);
// freopen("bzoj1056.out","w",stdout);
int T=read();id=++cnt;insert1(root,-inf,root);id=++cnt;insert1(root,inf,root);
int tt=0;
while(T--){
int op=read_s();ll x;//printf("%d\n",++tt);
if (!op){
x=read();
if (flag[id]) del(),insert1(root,x,root);
else insert1(root,x,root),flag[id]=1;
continue;
}
if (op==1){splay(id,root);W(size[c[id][0]]);write_char('\n');}
}flush();
return 0;
}