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

View Code
  1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <algorithm>
6
7 #define N 1111111
8 #define INF 1LL<<60
9 #define MOD 999997
10
11 using namespace std;
12
13 struct NA
14 {
15     char na[14];
16     int no;
17 }me[N];
18
19 long long val[N];
20 int fa[N],son[N][2],sz[N],no[N];
21 int root,n,spe,stk[N];
22 int q[N],top,cnt,hnt,tot;
24
25 inline void prt(int x)
26 {
27     if(!x) return;
28     prt(son[x][1]);
29     printf("%s     ",me[no[x]].na+1);
30     prt(son[x][0]);
31 }
32
33 inline void pushup(int x)
34 {
35     if(!x) return;
36     sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;
37 }
38
39 inline void link(int x,int y,int c)
40 {
41     fa[x]=y; son[y][c]=x;
42 }
43
44 inline void rotate(int x,int c)
45 {
46     int y=fa[x];
50     pushup(y);
51 }
52
53 inline void splay(int x,int g)
54 {
55     while(fa[x]!=g)
56     {
57         int y=fa[x];
58         int cy=son[fa[y]][1]==y,cx=son[y][1]==x;
59         if(fa[y]==g) rotate(x,cx);
60         else
61         {
62             if(cx==cy) rotate(y,cy);
63             else rotate(x,cx);
64             rotate(x,cy);
65         }
66     }
67     pushup(x);
68     if(!g) root=x;
69 }
70
71 inline int getnum()
72 {
73     if(top) return q[top--];
74     return ++cnt;
75 }
76
77 inline void newnode(int y,int &x,long long sp,int po)
78 {
79     x=getnum(); me[po].no=x;
80     fa[x]=y; val[x]=sp; no[x]=po; sz[x]=1;
81     son[x][0]=son[x][1]=0;
82 }
83
84 inline void init()
85 {
86     newnode(cnt=0,root,-INF,0);
87     newnode(root,son[root][1],INF,0);
88     sz[root]=2;
89 }
90
91 inline void insert(int po,long long sp)//数组位置，分值
92 {
93     int x=root;
94     while(son[x][sp>val[x]]) x=son[x][sp>val[x]];
95     newnode(x,son[x][sp>val[x]],sp,po);
96     splay(son[x][sp>val[x]],0);
97 }
98
99 inline int findrk(int rk)//排名rk的节点
100 {
101     int x=root;
102     while(x)
103     {
104         if(rk==sz[son[x][0]]) return x;
105         else if(rk<sz[son[x][0]]) x=son[x][0];
106         else rk-=sz[son[x][0]]+1,x=son[x][1];
107     }
108 }
109
110 inline int getmax(int x)
111 {
112     while(son[x][1]) x=son[x][1];
113     return x;
114 }
115
116 inline int getmin(int x)
117 {
118     while(son[x][0]) x=son[x][0];
119     return x;
120 }
121
122 inline void del(int sp)//删除下标sp的节点
123 {
124     splay(sp,0);
125     int x=getmax(son[sp][0]),y=getmin(son[sp][1]);
126     splay(x,0); splay(y,x);
127     q[++top]=son[y][0];
128     fa[son[y][0]]=0; son[y][0]=0;
129     pushup(y); pushup(x);
130 }
131
132 inline int gethash(char *s)
133 {
134     int rt=0;
135     int len=strlen(s+1);
136     for(int i=1;i<=len;i++)
137         rt=(rt*27+(s[i]-'A'+1))%MOD;
138     return rt;
139 }
140
141 inline int getpos(int z,char *s)
142 {
145     return -1;
146 }
147
148 inline void add(int u,int v)
149 {
151 }
152
153 inline void INSERT(char *s,long long sp)
154 {
155     int z=gethash(s);
156     int p=getpos(z,s);
157     if(p==-1)
158     {
160         for(int i=strlen(s+1)+1;i>=1;i--) me[hnt].na[i]=s[i];
161         insert(hnt,sp);
162     }
163     else
164     {
165         del(me[p].no);
166         insert(p,sp);
167     }
168 }
169
170 inline void dfs(int x)
171 {
172     if(!x) return;
173     dfs(son[x][1]);
174     stk[++spe]=no[x];
175     dfs(son[x][0]);
176 }
177
178 inline void QUERY(int st)
179 {
180     st=sz[root]-2-st+1;
181     int ed=max(st-9,1);
182     swap(st,ed);
183     int x=findrk(st-1),y=findrk(ed+1);
184     splay(x,0); splay(y,x);
185     spe=0;
186     dfs(son[y][0]);
187     for(int i=1;i<spe;i++) printf("%s ",me[stk[i]].na+1);
188     printf("%s\n",me[stk[spe]].na+1);
189 }
190
191 inline void QUERY(char *s)
192 {
193     int z=gethash(s);
194     int p=getpos(z,s);
195     splay(me[p].no,0);
196     printf("%d\n",sz[son[me[p].no][1]]);
197 }
198
199 inline void go()
200 {
201     char str[49],s[49];long long b;int bb;
203     init();
204     scanf("%d",&n);
205     while(n--)
206     {
207         scanf("%s",str);
208         if(str[0]=='+')
209         {
210             sscanf(str+1,"%s",s+1);
211             scanf("%lld",&b);
212             INSERT(s,b);
213         }
214         else if(str[1]>='0'&&str[1]<='9')
215             sscanf(str+1,"%d",&bb),QUERY(bb);
216         else sscanf(str+1,"%s",s+1),QUERY(s);
217     }
218 }
219
220 int main()
221 {
222     go();
223     return 0;
224 }

posted @ 2013-03-13 00:01  proverbs  阅读(1155)  评论(0编辑  收藏  举报