蒟蒻求调
查看原帖
蒟蒻求调
463956
incra楼主2023/7/24 10:45

不开O2 MLE,开了有时60,有时0

代码:

#include <iostream>
#include <ctime>
using namespace std;
const int N = 100010,INF = 2e8;
struct node {
	int l,r;
	int key,val;
	int size;
}tr[N];
int root,idx;
int n,m;
int a[N];
int new_node (int key) {
	tr[++idx] = {0,0,key,rand (),1};
	return idx;
}
void push_up (int u) {
	tr[u].size = tr[tr[u].l].size + tr[tr[u].r].size + 1;
}
void build () {
	new_node (-INF),new_node (INF);
	root = 1,tr[1].r = 2;
	if (tr[1].val < tr[2].val) root = 2,tr[2].l = 1;
	push_up (root);
}
void split_key (int u,int key,int &x,int &y) {
	if (!u) {
		x = y = 0;
		return ;
	}
	if (tr[u].key <= key) {
		x = u;
		split_key (tr[u].r,key,tr[x].r,y);
		push_up (x);
	}
	else {
		y = u;
		split_key (tr[u].l,key,x,tr[y].l);
		push_up (y);
	}
}
int merge (int x,int y) {
	if (!x || !y) return x + y;
	if (tr[x].val > tr[y].val) {
		tr[x].r = merge (tr[x].r,y);
		push_up (x);
		return x;
	}
	tr[y].l = merge (x,tr[y].l);
	push_up (y);
	return y;
}
void insert (int key) {
	int x,y;
	split_key (root,key,x,y);
	root = merge (merge (x,new_node (key)),y);
}
void erase (int key) {
	int x,y,z;
	split_key (root,key,x,z),split_key (x,key - 1,x,y);
	y = merge (tr[y].l,tr[y].r);
	root = merge (x,merge (y,z));
}
int get_rank_by_key (int p,int key) {
    if (!p) return 0;
    if (tr[p].key == key) return tr[tr[p].l].size + 1;
    if (tr[p].key > key) return get_rank_by_key (tr[p].l,key);
    return tr[tr[p].l].size + 1 + get_rank_by_key (tr[p].r,key);
}
int get_key_by_rank (int p,int rank) {
    if (!p) return INF;
    if (rank <= tr[tr[p].l].size) return get_key_by_rank (tr[p].l,rank);
    if (rank <= tr[tr[p].l].size + 1) return tr[p].key;
    return get_key_by_rank (tr[p].r,rank - tr[tr[p].l].size - 1);
}
int get_prev (int p,int key) {
    if (!p) return -INF;
    if (tr[p].key >= key) return get_prev (tr[p].l,key);
    return max (tr[p].key,get_prev (tr[p].r,key));
}
int get_next (int p,int key) {
    if (!p) return INF;
    if (tr[p].key <= key) return get_next (tr[p].r,key);
    return min (tr[p].key,get_next (tr[p].l,key));
}
int main () {
	srand (time (0));
	build ();
	cin >> n;
	while (n--) {
        int op,x;
        cin >> op >> x;
        if (op == 1) insert (x);
        else if (op == 2) erase (x);
        else if (op == 3) cout << get_rank_by_key (root,x) - 1 << endl;
        else if (op == 4) cout << get_key_by_rank (root,x + 1) << endl;
        else if (op == 5) cout << get_prev (root,x) << endl;
        else cout << get_next (root,x) << endl;
    }
	return 0;
}
2023/7/24 10:45
加载中...