hash 加上 平衡树(名次树)。
这道题麻烦的地方就在于输入的是一个名字,所以需要hash。
这个hash用的是向后探查避免冲突,如果用类似前向星的方式避免冲突,比较难写,容易挂掉,但也速度快些。
mod一定要取得大一些。 hash时要减去@,否则A和B的hash值会相同导致tle。
比较难写?//蒟蒻本性。。。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 1000000 + 10; const int mod = 999983; const int INF = 2147483647; int n,sp,p; char s[20],name[maxn][20],op; int res[20]; int h[maxn]; int cnt; struct Splay { int l[maxn],r[maxn],f[maxn]; int a[maxn],s[maxn]; int root; void update(int x) { s[x]=s[l[x]]+s[r[x]]+1; } void lr(int x) { int y=f[x]; r[y]=l[x]; if(l[x]) f[l[x]]=y; f[x]=f[y]; if(root==y) root=x; else if(l[f[y]]==y) l[f[y]]=x; else r[f[y]]=x; f[y]=x; l[x]=y; update(y); update(x); } void rr(int x) { int y=f[x]; l[y]=r[x]; if(r[x]) f[r[x]]=y; f[x]=f[y]; if(root==y) root=x; else if(l[f[y]]==y) l[f[y]]=x; else r[f[y]]=x; f[y]=x; r[x]=y; update(y); update(x); } void rotate(int x) { if(l[f[x]]==x) rr(x); else lr(x); } void splay(int x,int target=0) { while(f[x] != target) { if(f[f[x]]==target) rotate(x); else if((l[f[x]]==x) == (l[f[f[x]]]==f[x])) {rotate(f[x]); rotate(x);} else {rotate(x); rotate(x);} } } void insert(int pos,int val) { int x=root,y=0; while(x) { y=x; x=(val<=a[x]?l[x]:r[x]); } if(val<=a[y]) l[y]=pos; else r[y]=pos; f[pos]=y; l[pos]=r[pos]=0; a[pos]=val; s[pos]=1; splay(pos); } void erase(int x) { splay(x); if(!r[root]) { f[l[root]]=0; root=l[root]; } else { int y=r[x]; while(l[y]) y=l[y]; splay(y,root); l[y]=l[root]; f[l[root]]=y; f[y]=0; root=r[root]; update(root); } } int find(int k) { int x=root; while(s[r[x]]+1!=k) { if(k<s[r[x]]+1) x=r[x]; else {k-=s[r[x]]+1; x=l[x];} } return x; } int rank(int x) { splay(x); return s[r[x]]; } void access(int x) { if(!x) return; access(r[x]); res[++sp]=x; access(l[x]); } void init() { r[1]=2; f[2]=1; s[1]=2; s[2]=1; root=1; cnt=2; a[1]=-INF; a[2]=INF; } }splay; int hash(char* s) { int l=strlen(s),res=0; for(int i=0;i<l;i++) res=(res*27+(s[i]-'@'))%mod; return res; } int main() { scanf("%d ",&n); splay.init(); memset(h,0,sizeof(h)); while(n--) { while(op=getchar(),op!='?'&&op!='+'); if(op=='+') { scanf("%s%d",s,&p); int t=hash(s),pos=0; while(1) { if(!h[t]) { pos=t; break; } else if(!strcmp(name[h[t]],s)) {pos=t; break;} else {t++; if(t==(mod+1)) t=1;} } if(!h[pos]) { h[pos]=++cnt; memcpy(name[cnt],s,strlen(s)); splay.insert(cnt,p); } else { splay.erase(h[pos]); splay.insert(h[pos],p); } } else { scanf("%s",s); if(s[0]>='0' && s[0] <='9') { sscanf(s,"%d",&p); int x=p+1,y=min(p+10,splay.s[splay.root]-1); x=splay.find(x-1); y=splay.find(y+1); swap(x,y); splay.splay(x); splay.splay(y,splay.root); sp=0; splay.access(splay.l[splay.r[splay.root]]); for(int j=1;j<sp;j++) printf("%s ",name[res[j]]); printf("%s ",name[res[sp]]); } else { int t=hash(s); while(1) { if(!strcmp(s,name[h[t]])) { printf("%d ",splay.rank(h[t])); break; } else {t++; if(t==(mod+1)) t=1;} } } } } return 0; }