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 }
没有人能阻止我前进的步伐,除了我自己!