bzoj1056(挖个坑wa+tle,平衡树)

来源:互联网 发布:淘宝运营视频 编辑:程序博客网 时间:2024/06/05 08:50

2016.8.22:这坑已经放弃填了。。。。。。。。。。。

代码题。。。

虽然还没有过,但是有学了一些经验

1、中间就可以直接普通的输入输出了

freopen("rank.in","r",stdin);freopen("rank.out","w",stdout);<pre name="code" class="cpp"><span style="white-space:pre"></span>                                          <span style="white-space:pre"></span>  fclose(stdin);fclose(stdout);

2、发觉读题太关键了,这道题想当然的读错好几遍题。。。

3、注意样例,必须要先读懂样例才可以,样例给了很多的信息

#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<iostream>#define debug(x) cout<<#x<<"="<<x<<endlusing namespace std;typedef long long ll;const ll inf=0x3f3f3f3f;const ll N=250009;const ll mod=9875321; char name[N][12];ll n,hs[9875329],score[N];ll ch[N*2][2],tot,fa[2*N],size[N*2],v[N*2],id[N*2],rt,cnt[N];ll lin[N*2],head[N],last[N],next[N],end[N],bt;// lins//注意尽量不要和stl里面的东西重名,例如link,这里就要改为lin void up(ll i){size[i]=size[ch[i][0]]+size[ch[i][1]]+cnt[i];}inline ll read(){char ch;ll ans,f=1;while ((ch=getchar())<'0'||ch>'9') if (ch=='-') f=-1;ans=ch-'0';while ((ch=getchar())>='0'&&ch<='9') ans=ans*10+ch-'0';return ans*f;}void rot(ll x){ll y=fa[x],z=fa[y],l,r;if (ch[y][0]==x)l=0;else l=1;r=l^1;if (z)if (ch[z][0]==y) ch[z][0]=x;else ch[z][1]=x;fa[x]=z;fa[y]=x;fa[ch[x][r]]=y;ch[y][l]=ch[x][r];ch[x][r]=y;up(y);}void splay(ll x,ll k){ll y,z;while (fa[x]!=k){y=fa[x],z=fa[y];if (z!=k)if (ch[z][0]==y^ch[y][0]==x) rot(x);else rot(y);rot(x);}if (k==0) rt=x;up(x);}void insert(ll val,ll b){if (rt==0){rt=++tot;v[tot]=val;end[rt]=head[rt]=++bt;lin[bt]=b;cnt[tot]=1;up(tot);return;}ll i=rt,y;while (i){size[i]++;if (v[i]==val){cnt[i]++;lin[++bt]=b;next[head[i]]=bt;last[bt]=head[i];head[i]=bt;return;}y=ch[i][v[i]<val];if (!y){v[++tot]=val;cnt[tot]=1;size[tot]=1;end[tot]=head[tot]=++bt;lin[bt]=b;fa[tot]=i;ch[i][v[i]<val]=tot;i=tot;break;}i=y;}splay(i,0);}ll find(ll i,ll val){if (i==0) return 0;if (v[i]==val) return i;if (v[i]>val) return find(ch[i][0],val);return find(ch[i][1],val);}void del(ll val,ll r){ll k=find(rt,val);for (int j=end[k];j;j=next[j])if (lin[j]==r){next[last[j]]=next[j];last[next[j]]=last[j];if (head[k]==j) head[k]=last[j];if (end[k]==j) end[k]=next[j];break;}cnt[k]--;if (cnt[k]) return;splay(k,0);if (ch[k][0]==0&&ch[k][1]==0){rt=0;return;}if (ch[k][0]==0){rt=ch[k][1];fa[rt]=0;return;}if (ch[k][1]==0){rt=ch[k][0];fa[rt]=0;return;}ll y=ch[k][0];while (ch[y][1])y=ch[y][1];splay(y,k);fa[y]=0;fa[ch[k][1]]=y;rt=y;ch[y][1]=ch[k][1];up(y);}ll find_kth(ll i,ll k){if (i==0) return 0;if (size[ch[i][1]]>=k) return find_kth(ch[i][1],k);//调用函数时 if (size[ch[i][1]]+cnt[i]>=k) return i;return find_kth(ch[i][0],k-size[ch[i][1]]-cnt[i]);//注意不要名字打错,调用错了!!!! }void in(char *c,ll len){ll sco=read();ll k=0;for (int i=1;i<len;i++) k=((ll)k*29%mod+c[i]-'A'+1)%mod;if (hs[k]) {del(score[hs[k]],hs[k]);score[hs[k]]=sco;insert(sco,hs[k]);}else {score[++n]=sco;memcpy(name[n],c,len);hs[k]=n;insert(sco,n);}}void query_kth(char *c,ll len){ll k=0;for (int i=1;i<len;i++) k=k*10+c[i]-'0';ll h=find_kth(rt,k+1);splay(h,0);ll kk=0,g=0;for(int j=end[h];j;j=next[j]){g++;if (size[ch[h][1]]+g-1==k) break;}while (v[h]!=-inf){for (int j=end[h];j;j=next[j]){g--;if (g>0) continue;kk++;printf("%s ",name[lin[j]]+1);if (kk==10) {printf("\n");return;}}h=ch[h][0];while (ch[h][1]) h=ch[h][1];splay(h,0);}printf("\n");}void query_rank(char *c,ll len){ll k=0;for (int i=1;i<len;i++) k=((ll)k*29%mod+c[i]-'A'+1)%mod;ll h=find(rt,score[hs[k]]);splay(h,0);ll ans=size[ch[h][1]];for (int j=end[h];j;j=next[j]){ans++;if (lin[j]==hs[k]) break; }printf("%lld\n",ans-1);}int main(){//freopen("rank.in","r",stdin);//freopen("rank.out","w",stdout);ll q=read();char c[15];insert(inf,1);insert(-inf,2);tot=2;while (q--){scanf("%s",c);if (c[0]=='+') in(c,strlen(c));if (c[0]=='?')if (c[1]>='0'&&c[1]<='9') query_kth(c,strlen(c));else query_rank(c,strlen(c));}//fclose(stdin);//fclose(stdout);return 0;}


0 0
原创粉丝点击