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<<endl
using 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;
}