萌新初学OI,求助fhq-treap
查看原帖
萌新初学OI,求助fhq-treap
448884
快乐的大童楼主2022/4/8 22:25

RT,代码过了样例,TLE了

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <cmath>
using namespace std;

inline int R() {
	int x = 0, f = 1;
	char ch = getchar();
	while (!isdigit(ch)) {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (isdigit(ch)) {
		x = x * 10 + ch - 48;
		ch = getchar();
	}
	return x * f;
}

inline void write(int x) {
	if (x < 0) {
		x = -x;
		putchar('-');
	}
	int y = 0;
	char z[40];
	while (x || !y) {
		z[y++] = x % 10 + 48;
		x /= 10;
	}
	while (y--)
		putchar(z[y]);
	putchar(10);
}
const int N = 1e5 + 5;
int n, cnt, root, x, y, z;
int son[N][2], val[N], rnd[N], siz[N];

void pushup(int p) {
	siz[p] = siz[son[p][0]] + siz[son[p][1]] + 1;
}

void split(int p, int k, int &r1, int &r2) {
	if (!p) {
		r1 = r2 = 0;
		return;
	}
	if (val[p] <= k) {
		r1 = p;
		split(son[p][1], k, son[p][1], r2);
	} else {
		r2 = p;
		split(son[p][0], k, r1, son[p][0]);
	}
	pushup(p);
}

int merge(int r1, int r2) {
	if (!r1 || !r2)
		return r1 | r2;
	if (rnd[r1] < rnd[r2]) {
		son[r1][1] = merge(son[r1][1], r2);
		pushup(r1);
		return r1;
	} else {
		son[r2][0] = merge(r1, son[r2][0]);
		pushup(r2);
		return r2;
	}
}

int create(int a) {
	++cnt;
	val[cnt] = a;
	siz[cnt] = 1;
	rnd[cnt] = rand();
	return cnt;
}

void insert(int a) {
	int p = create(a);
	split(root, a, x, y);
	root = merge(merge(x, p), y);
}

void erase(int a) {
	split(root, a, x, y); //将l-r分裂成l-a和a+1-r
	split(x, a - 1, x, z); //将l-a分裂成l-(a-1)和a
	//x-->l-(a-1),z=a,y=(a+1)-r;
	z = merge(son[z][0], son[z][1]);
	root = merge(merge(x, y), z);
}

int kth(int p, int k) {
	while (1) {
		if (k <= siz[son[p][0]])
			p = son[p][0];
		else if (k == siz[son[p][0]] + 1)
			return p;
		else {
			k -= son[p][0] + 1;
			p = son[p][1];
		}
	}
}

void getrank(int k) {
	split(root, k - 1, x, y); //将l-r分裂成l-(k-1)和k-r
	write(siz[x] + 1);
	root = merge(merge(x, y), z);
}

void qianqu(int k) {
	split(root, k - 1, x, y); //将l-r分裂成l-(k-1)和k-r
	write(val[kth(x, siz[x])]);
	root = merge(merge(x, y), z);
}

void houji(int k) {
	split(root, k, x, y); //将l-r分裂成l-k和k+1-r
	write(val[kth(y, 1)]);
	root = merge(merge(x, y), z);
}

int main() {
	srand(time(0));
	n = R();
	for (int i = 1, op, k; i <= n; i++) {
		op = R(), k = R();
		if (op == 1) {
			insert(k);
		} else if (op == 2) {
			erase(k);
		} else if (op == 3) {
			getrank(k);
		} else if (op == 4) {
			write(val[kth(root, k)]);
		} else if (op == 5) {
			qianqu(k);
		} else {
			houji(k);
		}
	}
}
2022/4/8 22:25
加载中...