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 }

 

 

你可能感兴趣的:(hash)