题目大意:维护一种游戏排名系统,为他们的得分排序,若得分一样,则时间早的优先。有的时候要查询一个人是第几名,或者一段名次都是谁。
思路:拿到题一看就知道是暴力Treap乱搞,但是一查不知道看到了谁的文章,说Treap会T,我就战战兢兢的写了Splay,结果T了,拿到数据发现被一个点卡了100s。于是怒写Treap,1.2s怒切。
PS:千万不要相信谣言。。
CODE:
#include <cstdio> #include <cctype> #include <cstring> #include <iostream> #include <algorithm> #define MAX 300010 #define MO 299997 #define BASE 133 #define SIZE(a) ((a) == NULL ? 0:(a)->size) using namespace std; unsigned long long GetHash(char *s); struct HashSet{ int head[MAX],total; int next[MAX]; unsigned long long hash[MAX]; char src[MAX][12]; int Insert(char *s) { unsigned long long _hash = GetHash(s); int x = _hash % MO; for(int i = head[x]; i; i = next[i]) if(hash[i] == _hash) return i; next[++total] = head[x]; hash[total] = _hash; head[x] = total; strcpy(src[total],s); return total; } }map; struct Treap{ int random,val,T,name; int size; Treap *son[2]; Treap(int _,int __,int ___):val(_),T(__),name(___) { size = 1; son[0] = son[1] = NULL; random = rand(); } int Compare(int _val,int _T) { if(_val == val) { if(T == _T) return -1; return T < _T; } return val > _val; } void Maintain() { size = 1; if(son[0] != NULL) size += son[0]->size; if(son[1] != NULL) size += son[1]->size; } }*root = NULL; int cnt; int score; char c,name[12]; int now[MAX],_time[MAX]; unsigned long long GetHash(char *s) { unsigned long long re = 0; while(*s != '\0') re = re * BASE + *s++; return re; } inline void Rotate(Treap *&a,bool dir) { Treap *k = a->son[!dir]; a->son[!dir] = k->son[dir]; k->son[dir] = a; a->Maintain(),k->Maintain(); a = k; } void Insert(Treap *&a,int score,int t,int name) { if(a == NULL) { a = new Treap(score,t,name); return ; } int dir = a->Compare(score,t); Insert(a->son[dir],score,t,name); if(a->son[dir]->random > a->random) Rotate(a,!dir); a->Maintain(); } void Delete(Treap *&a,int score,int t) { int dir = a->Compare(score,t); if(dir != -1) Delete(a->son[dir],score,t); else { if(a->son[0] == NULL) a = a->son[1]; else if(a->son[1] == NULL) a = a->son[0]; else { int _ = (a->son[0]->random > a->son[1]->random); Rotate(a,_); Delete(a->son[_],score,t); } } if(a != NULL) a->Maintain(); } int Rank(Treap *a,int k) { if(k <= SIZE(a->son[0])) return Rank(a->son[0],k); k -= SIZE(a->son[0]); if(k == 1) return a->name; return Rank(a->son[1],k - 1); } int Find(Treap *a,int score,int t) { int dir = a->Compare(score,t); if(dir == 0) return Find(a->son[0],score,t); if(dir == -1) return SIZE(a->son[0]) + 1; return SIZE(a->son[0]) + 1 + Find(a->son[1],score,t); } int main() { cin >> cnt; for(int i = 1; i <= cnt; ++i) { while(c = getchar(),c == ' ' || c == '\n' || c == '\r' || c == '\t'); if(c == '+') { scanf("%s%d",name,&score); int x = map.Insert(name); if(now[x]) Delete(root,now[x],_time[x]); now[x] = score,_time[x] = i; Insert(root,now[x],_time[x],x); } else { c = getchar(); ungetc(c,stdin); if(isdigit(c)) { int st,ed; scanf("%d",&st); ed = min(st + 9,map.total); for(int i = st; i <= ed; ++i) { if(i != st) putchar(' '); printf("%s",map.src[Rank(root,i)]); } puts(""); } else { scanf("%s",name); int x = map.Insert(name); printf("%d\n",Find(root,now[x],_time[x])); } } } return 0; }