坑点超多,不过双倍经验还是很爽的…
要按双关键字排名题目根本就没有说啊囧LZ
不敢用map然后手写hash,结果…比map还慢…证明了本蒟蒻是有多弱…
AC code:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#include <vector>
using namespace std;
const int L=11;
const int N=250010;
int n,tot,cnt;
struct nod{
int sco,num,size,fix;
char name[L];
nod *lc,*rc,*pr;
friend bool operator<(nod x,nod y){
if(x.sco!=y.sco) return x.sco>y.sco;
return x.num<y.num;
}
}pool[N],*NIL;
struct data{
nod *pt;
char s[L];
};
vector<data> h[N];
struct Hash{
nod* get(char s[]){
int key=0,len=strlen(s);
for(int i=0,j=1;i<len;i++,j=(j*26)%N) key=(key+(s[i]-'A')*j)%N;
for(int i=0;i<(int)h[key].size();i++){
if(!strcmp(s,h[key][i].s)) return h[key][i].pt;
}
data t;
t.pt=&pool[tot++];strcpy(t.s,s);
h[key].push_back(t);
return t.pt;
}
}H;
struct Treap{
nod *root;
Treap(){
root=NIL=&pool[tot++];
}
void newnod(nod *&p,int sco,char name[]){
p->sco=sco;p->size=1;p->fix=rand();strcpy(p->name,name);
p->lc=p->rc=p->pr=NIL;
}
void update(nod *p){
p->size=p->lc->size+p->rc->size+1;
}
nod* merge(nod *p1,nod *p2){
if(p1==NIL) return p2;
if(p2==NIL) return p1;
if(p1->fix>p2->fix){
nod *p3=merge(p1->rc,p2);
p3->pr=p1;p1->rc=p3;
update(p1);
return p1;
}
nod *p3=merge(p1,p2->lc);
p3->pr=p2;p2->lc=p3;
update(p2);
return p2;
}
void split(nod *p,nod *&p1,nod *&p2,int k){
if(p==NIL){
p1=p2=NIL;
return ;
}
if(p->lc->size+1>k){
split(p->lc,p1,p2,k);
p->lc=p->pr=NIL;
p2=merge(p2,p);
update(p2);
}
else{
split(p->rc,p1,p2,k-p->lc->size-1);
p->rc=p->pr=NIL;
p1=merge(p,p1);
update(p1);
}
}
int getrank(nod *p){
int k=p->lc->size+1;
while(p->pr!=NIL){
if(p->pr->rc==p) k+=p->pr->lc->size+1;
p=p->pr;
}
return k;
}
int getrank(nod *p,nod *x){
if(p==NIL) return 0;
return *x<*p?getrank(p->lc,x):getrank(p->rc,x)+p->lc->size+1;
}
void insert(nod *p){
nod *p1,*p2;
split(root,p1,p2,getrank(root,p));
root=merge(merge(p1,p),p2);
}
void erase(nod *p){
nod *p1,*p2,*p3,*p4;
split(root,p1,p2,getrank(p)-1);
split(p2,p3,p4,1);
root=merge(p1,p4);
}
void getkth(int k){
nod *p1,*p2,*p3,*p4;
split(root,p1,p2,k-1);
split(p2,p3,p4,1);
printf("%s",p3->name);
root=merge(merge(p1,p3),p4);
}
}T;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x;
char c;
char s[L];
scanf("\n%c%s",&c,s);
if(c=='+'){
scanf("%d",&x);
nod *p=H.get(s);
if(!p->size){
T.newnod(p,x,s);
p->num=++cnt;
T.insert(p);
}
else{
T.erase(p);
p->sco=x;p->num=++cnt;
T.insert(p);
}
}
else{
if(s[0]>='0'&&s[0]<='9'){
int k=0,len=strlen(s);
for(int i=0;i<len;i++) k=k*10+s[i]-'0';
for(int i=0;i<10&&k+i<=T.root->size;i++){
if(i) printf(" ");
T.getkth(k+i);
}
printf("\n");
}
else printf("%d\n",T.getrank(H.get(s)));
}
}
return 0;
}