Subtask123 能过,是操作 1 的锅
#include <cstdio>
#include <algorithm>
using namespace std;
namespace sgt {
int lmin[18000000], rmin[18000000], qw[18000000], lbmax[18000000], rbmax[18000000];
int ls[18000000], rs[18000000]; int tots;
void tagl(int rt, int w) {lmin[rt] = min(lmin[rt], w);}
void tagr(int rt, int w) {rmin[rt] = min(rmin[rt], w);}
void tagw(int rt, int w) {qw[rt] = w; lmin[rt] = rmin[rt] = 1000000005;}
int copy(int &nrt, int rt) {
if (nrt != rt) return nrt;
nrt = ++tots, ls[nrt] = ls[rt], rs[nrt] = rs[rt], lmin[nrt] = lmin[rt];
rmin[nrt] = rmin[rt]; qw[nrt] = qw[rt]; lbmax[nrt] = lbmax[rt]; rbmax[nrt] = rbmax[rt];
return nrt;
}
void pushdown(int &nrt, int rt) {
copy(nrt, rt);
if (qw[nrt] != -1) {
tagw(copy(ls[nrt], ls[rt]), qw[nrt]); tagw(copy(rs[nrt], rs[rt]), qw[nrt]); qw[nrt] = -1;
}
if (lmin[nrt] != 1000000005) {
tagl(copy(ls[nrt], ls[rt]), lmin[nrt]);
tagl(copy(rs[nrt], rs[rt]), max(lmin[nrt], rbmax[ls[nrt]])); lmin[nrt] = 1000000005;
}
if (rmin[nrt] != 1000000005) {
tagr(copy(rs[nrt], rs[rt]), rmin[nrt]);
tagr(copy(ls[nrt], ls[rt]), max(rmin[nrt], lbmax[rs[nrt]])); rmin[nrt] = 1000000005;
}
}
void pushup(int rt) {
lbmax[rt] = max(lbmax[ls[rt]], lbmax[rs[rt]]);
rbmax[rt] = max(rbmax[ls[rt]], rbmax[rs[rt]]);
}
void build(int &rt, int l, int r, int *a) {
rt = ++tots; lmin[rt] = rmin[rt] = 1000000005; qw[rt] = -1;
if (l == r) return qw[rt] = 0, lbmax[rt] = a[l - 1], rbmax[rt] = a[l], void();
int mid = (l + r) >> 1; build(ls[rt], l, mid, a); build(rs[rt], mid + 1, r, a);
pushup(rt);
}
int queryLbound(int rt, int l, int r, int x, int w) {
int mid = (l + r) >> 1;
if (r <= x) {
if (lbmax[rt] < w) return -1; if (l == r) return l;
int tmp = queryLbound(rs[rt], mid + 1, r, x, w);
return tmp == -1 ? queryLbound(ls[rt], l, mid, x, w) : tmp;
}
if (x <= mid) return queryLbound(ls[rt], l, mid, x, w);
int tmp = queryLbound(rs[rt], mid + 1, r, x, w);
return tmp == -1 ? queryLbound(ls[rt], l, mid, x, w) : tmp;
}
int queryRbound(int rt, int l, int r, int x, int w) {
int mid = (l + r) >> 1;
if (l >= x) {
if (rbmax[rt] < w) return -1; if (l == r) return l;
int tmp = queryRbound(ls[rt], l, mid, x, w);
return tmp == -1 ? queryRbound(rs[rt], mid + 1, r, x, w) : tmp;
}
if (x > mid) return queryRbound(rs[rt], mid + 1, r, x, w);
int tmp = queryRbound(ls[rt], l, mid, x, w);
return tmp == -1 ? queryRbound(rs[rt], mid + 1, r, x, w) : tmp;
}
void modify0(int &nrt, int rt, int l, int r, int x, int y, int w) {
copy(nrt, rt); if (x <= l && r <= y) return tagw(nrt, w); int mid = (l + r) >> 1;
pushdown(nrt, rt); if (x <= mid) modify0(ls[nrt], ls[rt], l, mid, x, y, w);
if (y > mid) modify0(rs[nrt], rs[rt], mid + 1, r, x, y, w); pushup(rt);
}
int modify1L(int &nrt, int rt, int l, int r, int x, int Lmax = 0) {
copy(nrt, rt); if (r <= x) return tagr(nrt, Lmax), max(Lmax, lbmax[nrt]); int mid = (l + r) >> 1;
pushdown(nrt, rt); if (x <= mid) return modify1L(ls[nrt], ls[rt], l, mid, x, Lmax);
else return modify1L(ls[nrt], ls[rt], l, mid, x, modify1L(rs[nrt], rs[rt], mid + 1, r, x, Lmax));
}
int modify1R(int &nrt, int rt, int l, int r, int x, int Rmax = 0) {
copy(nrt, rt); if (l >= x) return tagl(nrt, Rmax), max(Rmax, rbmax[nrt]); int mid = (l + r) >> 1;
pushdown(nrt, rt); if (x > mid) return modify1R(rs[nrt], rs[rt], mid + 1, r, x, Rmax);
else return modify1R(rs[nrt], rs[rt], mid + 1, r, x, modify1R(ls[nrt], ls[rt], l, mid, x, Rmax));
}
void modify2L(int &nrt, int rt, int l, int r, int x, int w) {
copy(nrt, rt); if (l == r) return lbmax[nrt] = w, void(); int mid = (l + r) >> 1;
pushdown(nrt, rt); if (x <= mid) modify2L(ls[nrt], ls[rt], l, mid, x, w);
else modify2L(rs[nrt], rs[rt], mid + 1, r, x, w); pushup(rt);
}
void modify2R(int &nrt, int rt, int l, int r, int x, int w) {
copy(nrt, rt); if (l == r) return rbmax[nrt] = w, void(); int mid = (l + r) >> 1;
pushdown(nrt, rt); if (x <= mid) modify2R(ls[nrt], ls[rt], l, mid, x, w);
else modify2R(rs[nrt], rs[rt], mid + 1, r, x, w); pushup(rt);
}
int query3(int &nrt, int rt, int l, int r, int x) {
copy(nrt, rt); if (l == r) return min(min(lmin[nrt], qw[nrt]), rmin[nrt]); int mid = (l + r) >> 1;
pushdown(nrt, rt); if (x <= mid) return query3(ls[nrt], ls[rt], l, mid, x);
else return query3(rs[nrt], rs[rt], mid + 1, r, x);
}
}
int h[200005], rts[200005];
int main() {
int n, q; scanf("%d %d", &n, &q); for (int i = 1; i < n; i++) scanf("%d", &h[i]);
h[0] = h[n] = 1000000000; sgt::build(rts[0], 1, n, h);
for (int i = 1; i <= q; i++) {
int a, b, c, d; scanf("%d %d %d", &a, &b, &c); if (a == 0 || a == 2) scanf("%d", &d); rts[i] = rts[b];
if (a == 0) {
if (sgt::query3(rts[i], rts[b], 1, n, c) >= d) continue;
int Lb = sgt::queryLbound(rts[i], 1, n, c, d), Rb = sgt::queryRbound(rts[i], 1, n, c, d);
sgt::modify0(rts[i], rts[b], 1, n, Lb, Rb, d);
// printf("edit %d : %d ~ %d\n", d, Lb, Rb);
}
if (a == 1) {
sgt::modify1L(rts[i], rts[b], 1, n, c); sgt::modify1R(rts[i], rts[b], 1, n, c);
}
if (a == 2) {
sgt::modify2L(rts[i], rts[b], 1, n, c + 1, d); sgt::modify2R(rts[i], rts[b], 1, n, c, d);
}
if (a == 3) {
printf("%d\n", sgt::query3(rts[i] = rts[b], rts[b], 1, n, c));
}
// for (int i = 1; i <= sgt::tots; i++) {
// printf("%d: %d %d, %d %d %d %d %d\n", i, sgt::ls[i], sgt::rs[i], sgt::lmin[i], sgt::rmin[i], sgt::qw[i], sgt::lbmax[i], sgt::rbmax[i]);
// }
}
return 0;
}