您的位置:首页 > 其它

BZOJ 1056 [HAOI2008]排名系统 Splay+Hash

2013-03-13 00:01 288 查看
理清思路,在草稿纸上写清楚需要哪些数据结构,分别维护什么,这样以后再写,思路还是很清晰的。

就是好久不写数据结构,略微忘记了。。。

View Code

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>

#define N 1111111
#define INF 1LL<<60
#define MOD 999997

using namespace std;

struct NA
{
char na[14];
int no;
}me
;

long long val
;
int fa
,son
[2],sz
,no
;
int root,n,spe,stk
;
int q
,top,cnt,hnt,tot;
int head
,next
,to
;

inline void prt(int x)
{
if(!x) return;
prt(son[x][1]);
printf("%s     ",me[no[x]].na+1);
prt(son[x][0]);
}

inline void pushup(int x)
{
if(!x) return;
sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;
}

inline void link(int x,int y,int c)
{
fa[x]=y; son[y][c]=x;
}

inline void rotate(int x,int c)
{
int y=fa[x];
link(x,fa[y],son[fa[y]][1]==y);
link(son[x][!c],y,c);
link(y,x,!c);
pushup(y);
}

inline void splay(int x,int g)
{
while(fa[x]!=g)
{
int y=fa[x];
int cy=son[fa[y]][1]==y,cx=son[y][1]==x;
if(fa[y]==g) rotate(x,cx);
else
{
if(cx==cy) rotate(y,cy);
else rotate(x,cx);
rotate(x,cy);
}
}
pushup(x);
if(!g) root=x;
}

inline int getnum()
{
if(top) return q[top--];
return ++cnt;
}

inline void newnode(int y,int &x,long long sp,int po)
{
x=getnum(); me[po].no=x;
fa[x]=y; val[x]=sp; no[x]=po; sz[x]=1;
son[x][0]=son[x][1]=0;
}

inline void init()
{
newnode(cnt=0,root,-INF,0);
newnode(root,son[root][1],INF,0);
sz[root]=2;
}

inline void insert(int po,long long sp)//数组位置,分值
{
int x=root;
while(son[x][sp>val[x]]) x=son[x][sp>val[x]];
newnode(x,son[x][sp>val[x]],sp,po);
splay(son[x][sp>val[x]],0);
}

inline int findrk(int rk)//排名rk的节点
{
int x=root;
while(x)
{
if(rk==sz[son[x][0]]) return x;
else if(rk<sz[son[x][0]]) x=son[x][0];
else rk-=sz[son[x][0]]+1,x=son[x][1];
}
}

inline int getmax(int x)
{
while(son[x][1]) x=son[x][1];
return x;
}

inline int getmin(int x)
{
while(son[x][0]) x=son[x][0];
return x;
}

inline void del(int sp)//删除下标sp的节点
{
splay(sp,0);
int x=getmax(son[sp][0]),y=getmin(son[sp][1]);
splay(x,0); splay(y,x);
q[++top]=son[y][0];
fa[son[y][0]]=0; son[y][0]=0;
pushup(y); pushup(x);
}

inline int gethash(char *s)
{
int rt=0;
int len=strlen(s+1);
for(int i=1;i<=len;i++)
rt=(rt*27+(s[i]-'A'+1))%MOD;
return rt;
}

inline int getpos(int z,char *s)
{
for(int i=head[z];~i;i=next[i])
if(strcmp(s+1,me[to[i]].na+1)==0) return to[i];
return -1;
}

inline void add(int u,int v)
{
to[tot]=v; next[tot]=head[u]; head[u]=tot++;
}

inline void INSERT(char *s,long long sp)
{
int z=gethash(s);
int p=getpos(z,s);
if(p==-1)
{
++hnt; add(z,hnt);
for(int i=strlen(s+1)+1;i>=1;i--) me[hnt].na[i]=s[i];
insert(hnt,sp);
}
else
{
del(me[p].no);
insert(p,sp);
}
}

inline void dfs(int x)
{
if(!x) return;
dfs(son[x][1]);
stk[++spe]=no[x];
dfs(son[x][0]);
}

inline void QUERY(int st)
{
st=sz[root]-2-st+1;
int ed=max(st-9,1);
swap(st,ed);
int x=findrk(st-1),y=findrk(ed+1);
splay(x,0); splay(y,x);
spe=0;
dfs(son[y][0]);
for(int i=1;i<spe;i++) printf("%s ",me[stk[i]].na+1);
printf("%s\n",me[stk[spe]].na+1);
}

inline void QUERY(char *s)
{
int z=gethash(s);
int p=getpos(z,s);
splay(me[p].no,0);
printf("%d\n",sz[son[me[p].no][1]]);
}

inline void go()
{
char str[49],s[49];long long b;int bb;
memset(head,-1,sizeof head); tot=0;
init();
scanf("%d",&n);
while(n--)
{
scanf("%s",str);
if(str[0]=='+')
{
sscanf(str+1,"%s",s+1);
scanf("%lld",&b);
INSERT(s,b);
}
else if(str[1]>='0'&&str[1]<='9')
sscanf(str+1,"%d",&bb),QUERY(bb);
else sscanf(str+1,"%s",s+1),QUERY(s);
}
}

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