排名系统通常要应付三种请求:上传一条新的得分记录、查询某个玩家的当前排名以及返回某个区段内的排名记录。当某个玩家上传自己最新的得分记录时,他原有的得分记录会被删除。为了减轻服务器负担,在返回某个区段内的排名记录时,最多返回10条记录。

Solution

题没什么东西,都是平衡树基本操作,名字的关系用一个 unordered_map 暴力维护即可,就是各种麻烦

(居然写完就AC了?)

#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
const int N = 300005;

struct SplayTree {
	int k[N], sz[N], cnt[N], fa[N], ch[N][2], root;
	void pushup(int p) {
		sz[p] = sz[ch[p][0]] + sz[ch[p][1]] + cnt[p];
	}
	void rotate(int p) {
		int q = fa[p], y = fa[q], x = ch[q][1] == p;
		ch[q][x] = ch[p][x ^ 1]; fa[ch[q][x]] = q;
		ch[p][x ^ 1] = q; fa[q] = p; fa[p] = y;
		if (y) ch[y][ch[y][1] == q] = p;
		pushup(q); pushup(p);
	}
	void splay(int x) {
		for (int y; y = fa[x]; rotate(x))
			if (fa[y]) rotate((ch[fa[y]][0] == y) == (ch[y][0] == x) ? y : x);
		root = x;
	}
	int search(int v) {
		int p = root;
		while (p && (k[p] - v)) p = ch[p][k[p] < v];
		return p;
	}
	void insert(int v,int ind) {
		if (root == 0) {
			root = ind;
			k[root] = v;
			sz[root] = cnt[root] = 1;
		}
		else {
			int p = root;
			while (p && ch[p][k[p] < v]) p = ch[p][k[p] < v];
			ch[p][k[p] < v] = ind;
			fa[ind] = p;
			k[ind] = v; sz[ind] = cnt[ind] = 1;
			splay(ind);
		}
	}
	void remove(int p) {
		if (p == 0) return;
		splay(p);
		if (cnt[p] > 1) { cnt[p]--; sz[p]--; return; }
		int l = ch[p][0], r = ch[p][1];
		fa[l] = fa[r] = 0; ch[p][0] = ch[p][1] = 0;
		if (l == 0) { root = r; return; }
		if (r == 0) { root = l; return; }
		int t = l;
		while (t && ch[t][1]) t = ch[t][1];
		root = l; splay(t);
		ch[t][1] = r; fa[r] = t;
		pushup(t);
	}
	void remove_v(int v) {
		remove(search(v));
	}
	int rank(int p) {
		splay(p);
		return sz[ch[p][0]] + 1;
	}
	int rank_v(int v) {
		return rank(search(v));
	}
	int kth(int p, int k) {
		if (k <= sz[ch[p][0]]) return kth(ch[p][0], k);
		if (k <= sz[ch[p][0]] + cnt[p]) return p;
		else return kth(ch[p][1], k - sz[ch[p][0]] - cnt[p]);
	}
	int kth(int k0) {
		return kth(root, k0);
	}
	int kth_v(int k0) {
		return k[kth(k0)];
	}
	int prefix(int p) {
		splay(p);
		int t = ch[p][0];
		while (t && ch[t][1]) t = ch[t][1];
		return t;
	}
	int suffix(int p) {
		splay(p);
		int t = ch[p][1];
		while (t && ch[t][0]) t = ch[t][0];
		return t;
	}
} T;

int m,cnt;
string name[N];

unordered_map <string,int> mp;

signed main() {
    ios::sync_with_stdio(false);
    cin>>m;
    while(m--) {
        char c;
        cin>>c;
        string str; int x;
        switch(c) {
        case '+':

            cin>>str>>x;
            if(mp.find(str)==mp.end()) {
                ++cnt;
                mp[str]=cnt;
                name[cnt]=str;
                T.insert(x,cnt);
            }
            else {
                int p=mp[str];
                T.remove(p);
                T.insert(x,p);
            }
            break;
        case '?':
            cin>>str;
            if(str[0]>='0' && str[0]<='9') {
                stringstream ss(str);
                ss>>x;
                int p=T.kth(cnt-x+1);
                for(int j=1;j<=10;j++) {
                    cout<<name[p]<<" ";
                    p=T.prefix(p);
                    if(p==0) break;
                }
                cout<<endl;
            }
            else {
                x=mp[str];
                cout<<cnt-T.rank(x)+1<<endl;
            }
            break;
        }
    }
}

相关文章:

  • 2022-12-23
  • 2021-10-08
  • 2022-02-10
  • 2022-12-23
  • 2022-12-23
  • 2022-03-08
  • 2021-08-17
  • 2021-11-13
猜你喜欢
  • 2021-07-19
  • 2021-10-28
  • 2021-08-14
  • 2021-10-11
  • 2021-11-05
  • 2021-06-17
  • 2022-03-03
相关资源
相似解决方案