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;
 23 int head[N],next[N],to[N];
 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];
 47     link(x,fa[y],son[fa[y]][1]==y);
 48     link(son[x][!c],y,c);
 49     link(y,x,!c);
 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 {
143     for(int i=head[z];~i;i=next[i])
144         if(strcmp(s+1,me[to[i]].na+1)==0) return to[i];
145     return -1;
146 }
147 
148 inline void add(int u,int v)
149 {
150     to[tot]=v; next[tot]=head[u]; head[u]=tot++;
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     {
159         ++hnt; add(z,hnt);
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;
202     memset(head,-1,sizeof head); tot=0;
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  阅读(1164)  评论(0编辑  收藏  举报