bzoj1056
treap+stl
这道题终于A了
排名是按照分数为第一关键字,插入时间为第二关键字,然后就是treap基本操作了
#include<bits/stdc++.h> using namespace std; const int N = 250010; int n, Tim, root, score, rank; map<string, pair<int, int> > info; string ans[N]; char c[13]; struct Treap { int seed, cnt; pair<int, int> key[N]; int size[N], child[N][2], p[N]; int rand() { seed = abs(seed * 19992147 + 123456); return seed; } void update(int x) { size[x] = size[child[x][0]] + size[child[x][1]] + 1; } void rotate(int &x, int t) { int y = child[x][t]; child[x][t] = child[y][t ^ 1]; child[y][t ^ 1] = x; update(x); update(y); x = y; } void insert(int &x, pair<int, int> o) { if(x == 0) { p[x = ++cnt] = rand(); key[x] = o; size[x] = 1; } else { int t = o > key[x]; insert(child[x][t], o); if(p[child[x][t]] > p[x]) rotate(x, t); } update(x); } bool find(int x, pair<int, int> o) { if(x == 0) return false; if(key[x] == o) return true; return find(child[x][o > key[x]], o); } void erase(int &x, pair<int, int> o) { if(o == key[x]) { if(child[x][0] == 0 && child[x][1] == 0) { x = 0; return; } int t = p[child[x][0]] < p[child[x][1]]; rotate(x, t); erase(child[x][t ^ 1], o); } else erase(child[x][o > key[x]], o); update(x); } int query_name(int x, int rank) { if(size[child[x][1]] + 1 == rank) return -key[x].second; if(rank <= size[child[x][1]]) return query_name(child[x][1], rank); return query_name(child[x][0], rank - size[child[x][1]] - 1); } int query_rank(int x, pair<int, int> o) { if(x == 0) return 0; if(o == key[x]) return size[child[x][1]] + 1; else if(o > key[x]) return query_rank(child[x][1], o); else return query_rank(child[x][0], o) + size[child[x][1]] + 1; } } treap; int main() { scanf("%d", &n); while(n--) { pair<int, int> o; string s = ""; scanf("%s", c); for(int i = 0; i < strlen(c); ++i) s = s + c[i]; if(s[0] == '+') { scanf("%d", &score); s = s.substr(1, s.length() - 1); if(info.find(s) != info.end()) treap.erase(root, info[s]); info[s] = make_pair(score, -(++Tim)); ans[Tim] = s; treap.insert(root, info[s]); } if(s[0] == '?') { if(isdigit(s[1])) { rank = 0; for(int i = 1; i < s.length(); ++i) rank = rank * 10 + s[i] - '0'; int lim = min(treap.size[root], rank + 9); for(int i = rank; i <= lim; ++i) { int id = treap.query_name(root, i), pos = 0; while(isupper(ans[id][pos])) { putchar(ans[id][pos]); ++pos; } if(i != lim) putchar(' '); } putchar('\n'); } else { string name = s.substr(1, s.length() - 1); printf("%d\n", treap.query_rank(root, info[name])); } } } return 0; }