好一个五彩斑斓
查看原帖
好一个五彩斑斓
482610
Mortidesperatslav楼主2024/4/1 18:57

数组不开 1010 倍 RE 一些,开到 1010 倍 WA+TLE,开 1010 倍不开 O2 还会 MLE,还好有几个 AC。

写的 FHQ-Treap,怎么会是呢?

#include<bits/stdc++.h>
#define mxn 500005
using namespace std;
struct node{
	int ls, rs, vl, nc, siz, ct;//nc = nonce, 随机值 
}tr[mxn];
int cnt, rt, q;
int nw(int x){
	tr[++cnt].vl = x;
	tr[cnt].nc = rand();
	tr[cnt].siz = 1;
	tr[cnt].ct = 1;
	return cnt;
}
void pup(int u){
	tr[u].siz = tr[tr[u].ls].siz + tr[tr[u].rs].siz + tr[u].ct;
}
void build(){
	rt = nw(-1145141919);
	tr[rt].rs = nw(1145141919);
	pup(rt);
}
void rtt(int &u, int fx){
	if (fx == 0){
		int tmp = tr[u].rs;
		tr[u].rs = tr[tmp].ls;
		tr[tmp].ls = u;
		u = tmp;
		pup(tr[u].ls);
		pup(u);
	}else{
		int tmp = tr[u].ls;
		tr[u].ls = tr[tmp].rs;
		tr[tmp].rs = u;
		u = tmp;
		pup(tr[u].rs);
		pup(u);
	}
}
void ins(int &u, int x){
	if (u == 0){
		u = nw(x);
		return;
	}else{
		if (x == tr[u].vl)
			tr[u].ct++;
		else{
			if (x < tr[u].vl){
				ins(tr[u].ls, x);
				if (tr[u].nc < tr[tr[u].ls].nc)
					rtt(u, 1);
			}else{
				ins(tr[u].rs, x);
				if (tr[u].nc < tr[tr[u].rs].nc)
					rtt(u, 0);
			}
			pup(u);
		}
	}
}
void del(int &u, int x){
	if (!u)
		return;
	if (x == tr[u].vl){
		if (tr[u].ct > 1){
			tr[u].ct--;
			pup(u);
			return;
		}
		if (tr[u].ls || tr[u].rs){
			if (!tr[u].rs || tr[tr[u].ls].nc > tr[tr[u].rs].nc){
				rtt(u, 1);
				del(tr[u].rs, x);
			}else{
				rtt(u, 0);
				del(tr[u].ls, x);
			}
			pup(u);
		}else{
			u = 0;
			return;
		}
	}
	if (x < tr[u].vl)
		del(tr[u].ls, x);
	else
		del(tr[u].rs, x);
	pup(u);
}
int qrk(int u, int x){
	if (!u)
		return 1;
	if (x == tr[u].vl)
		return tr[tr[u].ls].siz + 1;
	else if (x < tr[u].vl)
		return qrk(tr[x].ls, x);
	else
		return tr[tr[u].ls].siz + tr[u].ct + qrk(tr[x].rs, x);
}
int qvl(int u, int rk){
	if (!u)
		return 1145141919;
	if (rk <= tr[tr[u].ls].siz)
		return qvl(tr[u].ls, rk);
	else if (rk <= tr[tr[u].ls].siz + tr[u].ct)
		return tr[u].vl;
	else
		return qvl(tr[u].rs, rk - tr[tr[u].ls].siz - tr[u].ct);
}
int qpr(int x){
	int u = rt, pr;
	while (u){
		if (tr[u].vl < x)
			pr = tr[u].vl, u = tr[u].rs;
		else
			u = tr[u].ls;
	}
	return pr;
}
int qnx(int x){
	int u = rt, nx;
	while (u){
		if (tr[u].vl > x)
			nx = tr[u].vl, u = tr[u].ls;
		else
			u = tr[u].rs;
	}
	return nx;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	build();
	cin >> q;
	while (q--){
		int op, x;
		cin >> op >> x;
		if (op == 1)
			ins(rt, x);
		else if (op == 2)
			del(rt, x);
		else if (op == 3)
			cout << qrk(rt, x) - 1 << "\n";
		else if (op == 4)
			cout << qvl(rt, x + 1) << "\n";
		else if (op == 5)
			cout << qpr(x) << "\n";
		else if (op == 6)
			cout << qnx(x) << "\n";
	}
}
2024/4/1 18:57
加载中...