全 RE 求助
查看原帖
全 RE 求助
958944
Union_Find楼主2024/6/26 13:38

为什么会全 RE?还是说数组不够大?

#include <bits/stdc++.h>
using namespace std;
#define ll int
#define il inline
#define N 100100
ll n, m, a[N], op, u, v, k;
struct trE{
	ll val, sz, cnt, tag;
}tre[N * 20];
ll en, son[N][2];	
il ll neww(ll val){
	tre[++en] = trE{val, 1, 1, rand()};
	son[en][0] = son[en][1] = 0;
	return en;
}
il void pu(ll p){tre[p].sz = tre[son[p][0]].sz + tre[son[p][1]].sz + tre[p].cnt;}
il void rtt(ll &p, ll d){
	ll s = son[p][d];
	son[p][d] = son[s][d ^ 1];
	son[s][d ^ 1] = p;
	pu(p);
	pu(s);
	p = s;
}
il void add(ll &p, ll val){
	if (p == 0) p = neww(val);
	else if (tre[p].val == val) tre[p].cnt++;
	else{
		if (tre[p].val > val){
			add (son[p][0], val);
			if (tre[son[p][0]].tag > tre[p].tag) rtt(p, 0);
		}
		else{
			add (son[p][1], val);
			if (tre[son[p][1]].tag > tre[p].tag) rtt(p, 1);
		}
	}
	pu(p);
}
il void del(ll &p, ll val){
	if (tre[p].val > val) del(son[p][0], val);
	else if (tre[p].val < val) del(son[p][1], val);
	else if (tre[p].cnt > 1) tre[p].cnt--;
	else{
		if (!son[p][0] && !son[p][1]) p = 0;
		else if (!son[p][0]) rtt(p, 1), del(son[p][0], val);
		else if (!son[p][1]) rtt(p, 0), del(son[p][1], val);
		else{
			if (tre[son[p][0]].tag > tre[son[p][1]].tag) rtt(p, 0), del(son[p][1], val);
			else rtt(p, 1), del(son[p][0], val);
		}
	}
	if (p) pu(p);
}
il ll rk(ll p, ll k){
	if (p == 0) return 0;
	if (tre[p].val > k) return rk(son[p][0], k);
	else if (tre[p].val == k) return tre[son[p][0]].sz;
	else return tre[son[p][0]].sz + tre[p].cnt + rk(son[p][1], k);
}
il ll pre(ll p, ll k){
	if (p == 0) return -2147483647;
	else if (tre[p].val >= k) return pre(son[p][0], k);
	else return max(tre[p].val, pre(son[p][1], k));
}
il ll nxt(ll p, ll k){
	if (p == 0) return 2147483647;
	else if (tre[p].val <= k) return nxt(son[p][1], k);
	else return min(tre[p].val, nxt(son[p][0], k));
}
struct SEG{
	ll l, r, rt;
}tr[N * 8];
il void build (ll p, ll l, ll r){
	tr[p].l = l, tr[p].r = r;
	for (int i = l; i <= r; i++) add(tr[p].rt, a[i]);
	if (l == r) return;
	ll mid = (l + r) >> 1;
	build (p << 1, l, mid);
	build (p << 1 | 1, mid + 1, r);
}
il void seg_add(ll p, ll x, ll k){
	del(tr[p].rt, a[x]);
	add(tr[p].rt, k);
	if (tr[p].l == tr[p].r) return;
	ll mid = (tr[p].l + tr[p].r) >> 1;
	if (x <= mid) seg_add(p << 1, x, k);
	else seg_add(p << 1 | 1, x, k);
}
il ll seg_rk(ll p, ll l, ll r, ll k){
	if (tr[p].l > r || tr[p].r < l) return 0;
	if (tr[p].l >= l && tr[p].r <= r) return rk(tr[p].rt, k);
	return seg_rk(p << 1, l, r, k) + seg_rk(p << 1 | 1, l, r, k);
}
il ll seg_kr(ll x, ll y, ll k){
	ll l = 0, r = 1e18;
	while (l < r){
		ll mid = (l + r + 1) >> 1;
		if (seg_rk(1, x, y, mid) < k) l = mid;
		else r = mid - 1;
	}
	return r;
}
il ll seg_pre(ll p, ll l, ll r, ll k){
	if (tr[p].l > r || tr[p].r < l) return -2147483647;
	if (tr[p].l >= l && tr[p].r <= r) return pre(tr[p].rt, k);
	return max(seg_pre(p << 1, l, r, k), seg_pre(p << 1 | 1, l, r, k));
}
il ll seg_nxt(ll p, ll l, ll r, ll k){
	if (tr[p].l > r || tr[p].r < l) return 2147483647;
	if (tr[p].l >= l && tr[p].r <= r) return nxt(tr[p].rt, k);
	return min(seg_nxt(p << 1, l, r, k), seg_nxt(p << 1 | 1, l, r, k));
}
int main(){
	srand(time(0));
	scanf ("%lld %lld", &n, &m);
	for (int i = 1; i <= n; i++) scanf ("%lld", &a[i]);
	build (1, 1, n);
	while (m--){
		scanf ("%lld %lld %lld", &op, &u, &v);
		if (op == 3){
			seg_add(1, u, v);
			a[u] = v;
		}
		else{
			scanf ("%lld", &k);
			if (op == 1) printf ("%lld\n", seg_rk(1, u, v, k) + 1);
			if (op == 2) printf ("%lld\n", seg_kr(u, v, k));
			if (op == 4) printf ("%lld\n", seg_pre(1, u, v, k));
			if (op == 5) printf ("%lld\n", seg_nxt(1, u, v, k));
		}
	}
	return 0;
}

2024/6/26 13:38
加载中...