线段树套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;
}