样例都没过,求助树套树板子题QAQ
查看原帖
样例都没过,求助树套树板子题QAQ
161221
FL4K楼主2021/1/16 20:10

线段树套splay,请各位大佬帮忙看看问题出在哪里了

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <queue>
#include <vector>
#include <map>
#include <cstdlib>
#include <ctime>
using namespace std;
#define ll long long
#define ull unsigned long long
#define lowbit(x) ((x) & (-x))
#define For(x, i, j) for (int x = (i); x <= (j); x++)
#define FOR(x, i, j) for (int x = (i); x >= (j); x--)
#define ls (o << 1)
#define rs (o << 1 | 1)
#define debug(x) cout << "debug : " << x << endl;
inline int read() {
	int x = 0, w = 1; char ch = getchar();
	while (ch < '0' || ch > '9') {if (ch == '-') w = -1; ch = getchar();}
	while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
	return x * w;
}
#define N 4000005
const int INF = 2147483647;
int n, m, MX, ask;
int NUM;
struct node {int fa, siz, recy, ch[2], val;} s[N]; 
int a[N], rt[N];
//==================  Splay
int ident(int x) {return s[s[x].fa].ch[1] == x;}
void pushup(ll x) {s[x].siz = s[s[x].ch[0]].siz + s[s[x].ch[1]].siz + s[x].recy;}
void connect(int x, int y, int son) {s[x].fa = y; s[y].ch[son] = x;}
void rotate(int x) {
	int y = s[x].fa, z = s[y].fa, opx = ident(x), opy = ident(y);
	int u = s[x].ch[opx ^ 1];
	connect(u, y, opx); connect(y, x, opx ^ 1); connect(x, z, opy);
	pushup(y); pushup(x);
}
void splay(int i, int from, int to) {
	while (s[from].fa != to) { 
		int up = s[from].fa, vp = s[up].fa;
		if (vp != to) ident(from) ^ ident(to) ? rotate(from) : rotate(up);
		rotate(from);
	}
	if (!to) rt[i] = from;
}
int findnum(int i, int val) {
	int now = rt[i];
	while (now) {
		if (s[now].val == val) {splay(i, now, 0); return now;}
		now = s[now].ch[val > s[now].val];
	} return 0;
}
void crenode(int val, int fa) {
	NUM++; s[NUM].val = val; s[NUM].fa = fa; s[NUM].siz = 1; s[NUM].recy = 1;
}
int insert(int i, int val) {
	if (!rt[i]) {crenode(val, 0); rt[i] = NUM; return NUM;}
	int now = rt[i];
	while (now) { 
		s[now].siz++;
		if (s[now].val == val) {s[now].recy++; return now;}
		int Next = (val <= s[now].val ? 0 : 1);
		if (!s[now].ch[Next]) {
			crenode(val, now); s[now].ch[Next] = NUM; 
			return NUM;
		} now = s[now].ch[Next];
	} return 0;
}
void add(int i, int val) {int ADD = insert(i, val); splay(i, ADD, 0);}
void destroy(int x) {s[x].val = s[x].fa = s[x].siz = s[x].recy = s[x].ch[0] = s[x].ch[1] = 0;}
void del(int i, int val) {
	int K = findnum(i, val); if (!K) return;
	if (s[K].recy > 1) {s[K].recy--; s[K].siz--; return;}
	else if (!s[K].ch[0]) {rt[i] = s[K].ch[1]; s[rt[i]].fa = 0;}
	else {
		int lmax = s[K].ch[0];
		while (s[lmax].ch[1]) lmax = s[lmax].ch[1];
		int r = s[K].ch[1];
		splay(i, lmax, s[K].ch[0]);
		connect(r, lmax, 1); connect(lmax, 0, 1);
		pushup(lmax);
	} destroy(K);
}
int findrank(int i, int val) {
	int now = rt[i], ans = 0;
	while (now) {
		if (val == s[now].val) {
			ans += s[s[now].ch[0]].siz;
			splay(i, now, rt[i]);
			return ans;
		} else {
			ans += (val > s[now].val) * (s[s[now].ch[0]].siz + s[now].recy);
			now = s[now].ch[val > s[now].val];
		}
	}
}
int qian(int i, int val) {
	int now = rt[i], ans = -INF;
	while (now) {
		if (val > s[now].val && s[now].val > ans) ans = s[now].val;
		now = s[now].ch[val > s[now].val];
	} return ans;
} 
int hou(int i, int val) {
	int now = rt[i], ans = INF;
	while (now) {
		if (val < s[now].val && s[now].val < ans) ans = s[now].val;
		now = s[now].ch[val >= s[now].val];
	} return ans;
} 
//==================  线段树
inline void seg_insert(int o, int l, int r, int x, int w) {
	insert(o, w);
	if (l == r) return;
	int mid = (l + r) >> 1;
	if (x <= mid) seg_insert(ls, l, mid, x, w);
	else seg_insert(rs, mid + 1, r, x, w);
} 
inline void seg_rank(int o, int l, int r, int x, int y, int v) {
	if (l == x && r == y) {ask += findrank(o, v); return;}
	int mid = (l + r) >> 1;
	if (y <= mid) seg_rank(ls, l, mid, x, y, v);
	else if (x > mid) seg_rank(rs, mid + 1, r, x, y, v);
	else seg_rank(ls, l, mid, x, mid, v), seg_rank(rs, mid + 1, r, mid + 1, y, v);
}
inline void seg_change(int o, int l, int r, int x, int v) {
	del(o, a[x]); insert(o, v); 
	if (l == r) {a[x] = v; return;}
	int mid = (l + r) >> 1;
	if (x <= mid) seg_change(ls, l, mid, x, v);
	else seg_change(rs, mid + 1, r, x, v);
}
inline void seg_qian(int o, int l, int r, int x, int y, int v) {
	if (l == x && r == y) {ask = max(ask, qian(o, v)); return;}
	int mid = (l + r) >> 1;	
	if (y <= mid) seg_qian(ls, l, mid, x, y, v);
	else if (x > mid) seg_qian(rs, mid + 1, r, x, y, v);
	else seg_qian(ls, l, mid, x, mid, v), seg_qian(rs, mid + 1, r, mid + 1, y, v);
}
inline void seg_hou(int o, int l, int r, int x, int y, int v) {
	if (l == x && r == y) {ask = min(ask, hou(o, v)); return;}
	int mid = (l + r) >> 1;
	if (y <= mid) seg_hou(ls, l, mid, x, y, v);
	else if (x > mid) seg_hou(rs, mid + 1, r, x, y, v);
	else seg_hou(ls, l, mid, x, mid, v), seg_hou(rs, mid + 1, r, mid + 1, y, v);
}
inline int getKth(int x, int y, int k) {
	int L = 0, R = MX + 1, MID;
	while (L < R) {
		MID = (L + R) >> 1;
		ask = 0; seg_rank(1, 1, n, x, y, MID);
		if (ask < k) L = MID + 1;
		else R = MID;
	} return L - 1;
}
int main() {
	n = read(); m = read();
	For(i, 1, n) {
		a[i] = read();
		seg_insert(1, 1, n, i, a[i]);
		MX = max(MX, a[i]);
	}
	while (m--) {
		int opt, x, y, z;
		opt = read(), x = read(), y = read();
		if (opt == 1) z = read(), ask = 0, seg_rank(1, 1, n, x, y, z), printf("%d\n", ask + 1);
		else if (opt == 2) z = read(), printf("%d\n", getKth(x, y, z)); 
		else if (opt == 3) seg_change(1, 1, n, x, y), MX = max(MX, y);
		else if (opt == 4) z = read(), ask = -INF, seg_qian(1, 1, n, x, y, z), printf("%d\n", ask);
		else z = read(), ask = INF, seg_hou(1, 1, n, x, y, z), printf("%d\n", ask);
	}
	return 0;
}
2021/1/16 20:10
加载中...