刚学Treap,求助
查看原帖
刚学Treap,求助
86971
TRZ_2007楼主2020/12/16 19:37

WA + MLE,0pts,能过样例,表示很奇怪。

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 9;
const int inf = 0x3f3f3f3f;

int broot;

inline void read(int &x) {
	int f = 1; x = 0;
	char ch = getchar();
	while(!isdigit(ch)) {
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while(isdigit(ch)) {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	x = x * f;
}

struct node {
	int val,size,same,key;
	int l,r;
}tree[N];

#define ls tree[root].l
#define rs tree[root].r
#define push_up(root) tree[root].size = tree[ls].size + tree[rs].size + tree[root].same

int n,cnt;
int flag,x;

void rotate_right(int &root) {
	int tmp = rs;
	rs = tree[tmp].l;
	tree[tmp].l = tmp;
	push_up(root);
	push_up(tmp);
	root = tmp;
}

void rotate_left(int &root) {
	int tmp = ls;
	ls = tree[tmp].r;
	tree[tmp].r = tmp;
	push_up(root);
	push_up(tmp);
	root = tmp;
}

inline void insert(int &root,int x) {
	if(!root) {
		root = ++cnt;
		tree[root].size = tree[root].same = 1;
		tree[root].val = x; tree[root].key = rand();
		return;
	}
	if(tree[root].val == x) {
		++tree[root].same;
		++tree[root].size; 
		return;
	}
	int comp = (x > tree[root].val);
	if(comp) {
		insert(rs,x);
		if(tree[root].key < tree[rs].key) rotate_left(root);
	}
	else {
		insert(ls,x);
		if(tree[root].key < tree[ls].key) rotate_right(root);
	}
	push_up(root);
}

inline void del(int &root,int x) {
	if(!root) return;
	if(x < tree[root].val) del(ls,x);
	else if(x > tree[root].val) del(rs,x);
	else {
		if(ls == rs && rs == 0) {
			--tree[root].same;
			--tree[root].size;
			if(!tree[root].same) root = 0;
		}
		if(ls != 0 && rs == 0) {
			rotate_right(root);
			del(rs,x);
		}
		if(ls == 0 && rs != 0) {
			rotate_left(root);
			del(ls,x);
		}
		if(ls != 0 && rs != 0) {
			int comp = (tree[ls].key > tree[rs].key);
			if(comp) {
				rotate_right(root);
				del(rs,x);
			}else {
				rotate_left(root);
				del(ls,x);
			}
		}
	}
	push_up(root);
}

inline int rank(int root,int x) {
	if(!root) return 0;
	if(tree[root].val == x) return tree[ls].size + 1;
	if(tree[root].val > x) return rank(ls,x);
	if(tree[root].val < x) return rank(rs,x) + tree[ls].size + tree[root].same;
}

inline int find(int root,int x) {
	if(!root) return 0;
	if(tree[ls].size >= x) return find(ls,x);
	else {
		if(tree[ls].size + tree[root].same < x) return rank(rs,x - tree[ls].size - tree[root].same);
		else return tree[root].val;
	}
}

inline int pre(int root,int x) {
	if(!root) return -inf;
	if(tree[root].val >= x) return pre(ls,x);
	else return max(tree[root].val,pre(rs,x));
}

inline int suc(int root,int x) {
	if(!root) return inf;
	if(tree[root].val <= x) return suc(rs,x);
	else return min(tree[root].val,suc(ls,x));
}

int main() {
	read(n);
	for(int i = 1;i <= n;i++) {
		read(flag); read(x);
		if(flag == 1) insert(broot,x);
		if(flag == 2) del(broot,x);
		if(flag == 3) printf("%d\n",rank(broot,x));
		if(flag == 4) printf("%d\n",find(broot,x));
		if(flag == 5) printf("%d\n",pre(broot,x));
		if(flag == 6) printf("%d\n",suc(broot,x));
	}
	return 0;
} 
2020/12/16 19:37
加载中...