您的位置:首页 > 其它

BZOJ 1056——HAOI 2008 排名系统

2012-09-24 10:57 302 查看
http://61.187.179.132/JudgeOnline/problem.php?id=1056

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

20%数据满足N<=100
100%数据满足N<=250000

Source

题解:

  赤裸裸的数据结构题啊,乱维护一下hash值再怎么乱搞一下就行了,但是我的splay肿么调都调不过,始终T………………于是改写treap了,比splay快多了,再也不相信splay了……………………

View Code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<map>

using namespace std;

#define ull unsigned long long

const int maxn=220010;
const ull seed=99991;

int n,cnt,nowcnt,l;

char s[13],ss[maxn][13];

struct rec
{
int v,t;
rec(){}
rec(int a,int b)
{
v=a;t=b;
}
bool operator<(const rec &a)const
{
if (v==a.v) return t>a.t;
else return v<a.v;
}
bool operator==(const rec &a)const
{
return v==a.v && t==a.t;
}
}wmt[maxn];

map<ull , int> ma;

struct node
{
int l,r,size,id,fix;
rec v;
};

struct treap
{
node z[maxn];
int osize,size,root;
treap()
{
osize=size=root=0;
}
void update(int now)
{
z[now].size=z[z[now].l].size+z[z[now].r].size+1;
}
void rot_r(int &now)
{
int a=z[now].l;
z[now].l=z[a].r;
z[a].r=now;
update(now);
update(a);
now=a;
}
void rot_l(int &now)
{
int a=z[now].r;
z[now].r=z[a].l;
z[a].l=now;
update(now);
update(a);
now=a;
}
void insert(int &now,rec v)
{
if (now==0)
{
osize++;
size++;
now=size;
z[now].l=z[now].r=0;
z[now].v=v;
z[now].fix=rand();
z[now].id=nowcnt;
z[now].size=1;
return;
}
if (z[now].v<v)
{
insert(z[now].l,v);
update(now);
if (z[z[now].l].fix>z[now].fix) rot_r(now);
}
else
{
insert(z[now].r,v);
update(now);
if (z[z[now].r].fix>z[now].fix) rot_l(now);
}
}
void del(int &now,rec v)
{
if (now==0) return;
if (z[now].v<v) del(z[now].l,v);
else
{
if (v<z[now].v) del(z[now].r,v);
else
{
if ((z[now].l==0) && (z[now].r==0))
{
osize--;
now=0;
return;
}
if (z[now].l==0)
{
osize--;
now=z[now].r;
return;
}
if (z[now].r==0)
{
osize--;
now=z[now].l;
return;
}
if (z[z[now].l].fix<z[z[now].r].fix)
{
rot_l(now);
del(z[now].l,v);
update(now);
}
else
{
rot_r(now);
del(z[now].r,v);
update(now);
}
}
}
update(now);
}
int rank(rec now)
{
int p=root,ans=0;
while (p)
{
if (z[p].v==now) return ans+z[z[p].l].size+1;
if (now<z[p].v) ans+=z[z[p].l].size+1,p=z[p].r;
else p=z[p].l;
}
return 0;
}
void dfs(int p)
{
if (cnt>=10) return;
if (z[p].l) dfs(z[p].l);
if (cnt>=10) return;
printf("%s ",ss[z[p].id]);
cnt++;
if (cnt>=10) return;
if (z[p].r) dfs(z[p].r);
}
void find(int v)
{
int p=root;
while (v)
{
if (z[z[p].l].size+1==v) break;
if (v>z[z[p].l].size) v-=z[z[p].l].size+1,p=z[p].r;
else p=z[p].l;
}
printf("%s",ss[z[p].id]);
}
}tree;

ull hash()
{
int l=strlen(s);
ull ans=0;
for (int a=0;a<l;a++)
ans=(ans*seed+s[a]-'A'+1);
return ans;
}

int main()
{
freopen("rank.in","r",stdin);
freopen("rank.out","w",stdout);

scanf("%d",&n);
char c='!';
while (c!='\n' && c!='\r')
scanf("%c",&c);
int v,nowid,nowl;
ull ha;
for (int a=1;a<=n;a++)
{
scanf("%c",&c);
if (c=='+')
{
scanf("%s",s);
scanf("%d",&v);
ha=hash();
nowid=ma[ha];
if (nowid==0)
{
l++;
wmt[l]=rec(v,a);
nowcnt=l;
for (int b=0;b<=12;b++)
ss[l][b]=s[b];
ma[ha]=l;
}
else
{
nowcnt=nowid;
tree.del(tree.root,wmt[nowcnt]);
wmt[nowid]=rec(v,a);
}
tree.insert(tree.root,rec(v,a));
}
else
{
scanf("%s",s);
if (s[0]>='0' && s[0]<='9')
{
v=0;
nowl=strlen(s);
for (int b=0;b<nowl;b++)
v=v*10+s[b]-'0';
int maxsize=min(tree.osize,v+9);
for (int b=v;b<=maxsize;b++)
{
tree.find(b);
if (b==maxsize) printf("\n");
else printf(" ");
}
}
else
{
ha=hash();
printf("%d\n",tree.rank(wmt[ma[ha]]));
}
}
c='!';
while (~scanf("%c",&c))
if (c=='\n' || c=='\r') break;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: