题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1862
** http://www.lydsy.com/JudgeOnline/problem.php?id=1056**
思路:用一棵平衡树维护用户分数排名,然后用一棵Trie或者是HASH来维护用户ID。(看到P1862的内存64M果断放弃前缀树写HASH~~)(注:样例里的那些乱七八糟的注释还有回车之类的其实是没有的。)
代码:
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAX 801959
//------------------------Size_Balanced_Tree------------------------------------
struct node {
string name;
int S,T,s;
node *left,*right;
};
node *bank=new(node),*roof;
void INIT_SBT(){
bank->s=0;
roof=bank->left=bank->right=bank;
srand(29);
}
void left_ratote(node* &t){
node *k=t->right;
t->right=k->left;
t->s=t->left->s+t->right->s+1;
k->left=t;
k->s=k->left->s+k->right->s+1;
t=k;
}
void right_ratote(node* &t){
node *k=t->left;
t->left=k->right;
t->s=t->left->s+t->right->s+1;
k->right=t;
k->s=k->left->s+k->right->s+1;
t=k;
}
void maintain(node* &t){
if (t->left->left->s>t->right->s){
right_ratote(t);
maintain(t->right);
maintain(t);
return ;
}
if (t->left->right->s>t->right->s){
left_ratote(t->left);
right_ratote(t);
maintain(t->left);
maintain(t->right);
maintain(t);
return ;
}
if (t->right->right->s>t->left->s){
left_ratote(t);
maintain(t->left);
maintain(t);
return ;
}
if (t->right->left->s>t->left->s){
right_ratote(t->right);
left_ratote(t);
maintain(t->left);
maintain(t->right);
maintain(t);
return ;
}
}
void INSERT(int S,int T,string name,node* &t){
if (t==bank){
t=new(node);
t->s=1;
t->S=S;
t->T=T;
t->name=name;
t->left=t->right=bank;
return ;
}
t->s++;
if (SS||(S==t->S&&T>t->T)){
INSERT(S,T,name,t->left);
} else INSERT(S,T,name,t->right);
maintain(t);
}
void DELETE(int S,int T,node* &t){
if (S==t->S&&T==t->T){
if (t->left==bank&&t->right==bank){
delete(t);
t=bank;
return ;
}
if (t->left==bank){
node *k=t->right;
delete(t);
t=k;
return ;
}
if (t->right==bank){
node *k=t->left;
delete(t);
t=k;
return ;
}
if (rand()%2){
left_ratote(t);
DELETE(S,T,t->left);
} else {
right_ratote(t);
DELETE(S,T,t->right);
}
} else
if (SS||(S==t->S&&T>t->T)){
DELETE(S,T,t->left);
} else {
DELETE(S,T,t->right);
}
t->s=t->left->s+t->right->s+1;
maintain(t);
}
string select(int rank,node *t){
if (rank-1==t->right->s){
return t->name;
}
if (rank-1right->s){
return select(rank,t->right);
} else return select(rank-t->right->s-1,t->left);
}
int rank(int S,int T,node *t){
if (t==bank){
return 0;
}
if (t->S==S&&T==t->T){
return t->right->s;
}
if (SS||(S==t->S&&T>t->T)){
return rank(S,T,t->left)+t->right->s+1;
} else return rank(S,T,t->right);
}
//--------------------------Hash------------------------------------------------
const int p[10]={399239,159017,76207,39971,18313,10657,6133,5371,1987,541};
int hash(string s){
int rec=0;
for (int i=0;i='A'&&s[j]<='Z'){
c=c+s[j];
} else break;
}
int x;
scanf("%d",&x);
int y=hash(c);
bool flag=false;
while (T[y]){
if (Name[y]==c){
flag=true;
break;
};
y++;
y%=MAX;
}
if (flag){
DELETE(S[y],T[y],roof);
} else N++;
S[y]=x;
T[y]=i;
Name[y]=c;
INSERT(S[y],T[y],Name[y],roof);
} else {
if (s[1]>='A'&&s[1]<='Z'){
string c;
c="";
for (int j=1;j='A'&&s[j]<='Z'){
c=c+s[j];
} else break;
}
int y=hash(c);
while (Name[y]!=c){
y++;
y%=MAX;
}
printf("%d\n",rank(S[y],T[y],roof)+1);
} else {
int x=0;
for (int j=1;j='0'&&s[j]<='9'){
x*=10;
x+=int(s[j])-int('0');
} else break;
}
for (int j=x;j<=min(x+9,N)-1;j++){
string c=select(j,roof);
for (int k=0;k