线段树套fhq求助
查看原帖
线段树套fhq求助
300313
_luanyi_楼主2022/3/14 20:22

rt,WA#8,TLE#2#9(O2)#1,2,3,5,6,9,10(without O2)

#include <bits/stdc++.h>
#define fq(i,a,b) for (int i = (a); i <= (b); i++)
#define fnq(i,a,b) for (int i = (a); i < (b); i++)
#define nfq(i,a,b) for (int i = (a); i >= (b); i--)
#define nfnq(i,a,b) for (int i = (a); i > (b); i--)
#define elif else if
using namespace std;

//#define int long long

inline int rd () {
	int f = 1;
	char ch = getchar ();
	while (!isdigit (ch)) (ch == '-' ? (f = -1) : 0), ch = getchar ();
	int num = 0;
	while (isdigit (ch)) num = num * 10 + ch - '0', ch = getchar ();
	return num * f;
}
#define d rd ()

const int maxn = 50500;
struct node {
	int l, r, sz, pri;
	int key;
	node () {}
	node (int k) {
		l = r = 0;
		sz = 1;
		pri = rand ();
		key = k;
	}
} p[maxn << 7]; int cnt = 0;
int addnode (int key) {p[++cnt] = node (key); return cnt;}
void push_up (int rt) {p[rt].sz = p[p[rt].l].sz + p[p[rt].r].sz + 1;}
pair <int, int> split (int rt, int key) {
	if (!rt) return make_pair (0, 0);
	if (p[rt].key >= key) {
		pair <int, int> q = split (p[rt].l, key);
		p[rt].l = q.second;
		push_up (rt);
		return make_pair (q.first, rt);
	} else {
		pair <int, int> q = split (p[rt].r, key);
		p[rt].r = q.first;
		push_up (rt);
		return make_pair (rt, q.second);
	}
}
int merge (int l, int r) {
	if (!l) return r; if (!r) return l;
	if (p[l].pri > p[r].pri) {
		p[l].r = merge (p[l].r, r);
		push_up (l);
		return l;
	} else {
		p[r].l = merge (l, p[r].l);
		push_up (r);
		return r;
	}
}

void insert (int &rt, int x) {
	pair <int, int> q = split (rt, x);
	rt = merge (q.first, merge (addnode (x), q.second));
}
void erase (int &rt, int x) {
	pair <int, int> q = split (rt, x);
	pair <int, int> r = split (q.second, x + 1);
	rt = merge (q.first, merge (merge (p[r.first].l, p[r.first].r), r.second));
}
int getrnk (int &rt, int x) {
	pair <int, int> q = split (rt, x);
	int ans = p[q.first].sz;
	rt = merge (q.first, q.second);
	return ans;
}
int getval (int rt, int x) {
	if (x <= 0) return -2147483647;
	if (x > p[rt].sz) return 2147483647;
	if (p[p[rt].l].sz >= x) return getval (p[rt].l, x);
	x -= p[p[rt].l].sz + 1;
	if (!x) return p[rt].key;
	return getval (p[rt].r, x);
}
int getpre (int rt, int x) {return getval (rt, getrnk (rt, x));}
int getnxt (int rt, int x) {return getval (rt, getrnk (rt, x + 1) + 1);}

int a[maxn], tree[maxn << 2];
#define mid ((l + r) >> 1)
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
void build (int l, int r, int rt) {
	insert (tree[rt], -2147483647);
	insert (tree[rt], 2147483647);
	fq (i, l, r) insert (tree[rt], a[i]);
	if (l == r) return;
	build (lson); build (rson);
}
void upd (int l, int r, int rt, int p, int x) {
	erase (tree[rt], a[p]); insert (tree[rt], x);
	if (l == r) return;
	if (p <= mid) upd (lson, p, x);
	else upd (rson, p, x);
}
int _getrnk (int L, int R, int l, int r, int rt, int x) {
	if (L <= l && r <= R) return getrnk (tree[rt], x);
	int ans = 0;
	if (L <= mid) ans += _getrnk (L, R, lson, x);
	if (R > mid) ans += _getrnk (L, R, rson, x);
	if (L <= mid && R > mid) --ans;
	return ans;
}
int n = d;
int _getval (int L, int R, int k) {
	int ans = -1, l = 0, r = 1e8;
	while (l <= r) {
		if (_getrnk (L, R, 1, n, 1, mid) <= k) l = mid + 1;
		else ans = mid, r = mid - 1;
	}
	return ans - 1;
}
int _getpre (int L, int R, int l, int r, int rt, int x) {
	if (L <= l && r <= R) return getpre (tree[rt], x);
	int ans = -2147483647;
	if (L <= mid) ans = max (ans, _getpre (L, R, lson, x));
	if (R > mid) ans = max (ans, _getpre (L, R, rson, x));
	return ans;
}
int _getnxt (int L, int R, int l, int r, int rt, int x) {
	if (L <= l && r <= R) return getnxt (tree[rt], x);
	int ans = 2147483647;
	if (L <= mid) ans = min (ans, _getnxt (L, R, lson, x));
	if (R > mid) ans = min (ans, _getnxt (L, R, rson, x));
	return ans;
}
int m = d;
signed main () {
	fq (i, 1, n) a[i] = d;
	build (1, n, 1);
	while (m--) {
		int op = d;
		if (op == 1) {
			int l = d, r = d, k = d;
			printf ("%d\n", _getrnk (l, r, 1, n, 1, k));
		} elif (op == 2) {
			int l = d, r = d, k = d;
			printf ("%d\n", _getval (l, r, k));
		} elif (op == 3) {
			int p = d, x = d;
			upd (1, n, 1, p, x);
			a[p] = x;
		} elif (op == 4) {
			int l = d, r = d, k = d;
			printf ("%d\n", _getpre (l, r, 1, n, 1, k));
		} else {
			int l = d, r = d, k = d;
			printf ("%d\n", _getnxt (l, r, 1, n, 1, k));
		}
	}
	return 0;
}

哪位神犇能为我指点迷津,万分感谢!

2022/3/14 20:22
加载中...