RT, 突然发现48pts的做法假掉了
#include<bits/stdc++.h>
//#define int long long
#define INF 2147483647
#define HDF_LOVES_YDMY 1
//#define getchar getchar_unlocked
namespace IO {
inline int read() {
int ret = 0, f = 1;char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -f;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
ret = (ret << 1) + (ret << 3) + (ch ^ 48);
ch = getchar();
}
return ret * f;
}
// const int SIZE = 1 << 14;
// char getc() {
// static char buf[SIZE], *begin = buf, *end = buf;
// if (begin == end) {
// begin = buf;
// end = buf + fread(buf, 1, SIZE, stdin);
// }
// return *begin++;
// }
//
// int read() {
// int ret = 0, f = 1;char ch = getc();
// while (!isdigit(ch)) f |= ch == '-', ch = getc();
// while (isdigit(ch)) ret = (ret << 1) + (ret << 3) + (ch ^ 48), ch = getc();
// return ret * f;
// }
void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
}
using namespace IO;
using namespace std;
const int maxn = 4e5 + 500;
//const int qmaxn = 500 + 5;
int n, m;
int a[maxn], L[maxn], R[maxn], num[maxn], f[maxn], lazy[maxn], lastans, Maxa[maxn];
void init() {
int x = sqrt(n);
for (int i = 1;i <= x;i++) {
L[i] = (i - 1) * x + 1;
R[i] = i * x;
if (i == 1) L[i] = 2;
for (int j = L[i];j <= R[i];j++) {
num[j] = i;
Maxa[i] = max(a[j], Maxa[i]);
f[j] = (a[j] < L[i]) ? a[j] : f[a[j]];
}
}
if (R[x] != n) {
x++;
L[x] = R[x - 1] + 1;
R[x] = n;
for (int i = L[x];i <= R[x];i++) {
num[i] = x;
f[i] = (a[i] < L[x]) ? a[i] : f[a[i]];
Maxa[x] = max(a[i], Maxa[x]);
}
}
return;
}
void renew(int nowk) {
// if (!lazy[nowk]) return;
Maxa[nowk] = -INF;
for (int i = L[nowk];i <= R[nowk];i++) {
// a[i] = max(a[i] - lazy[nowk], 1ll);
a[i] = max(a[i] - lazy[nowk], 1);
Maxa[nowk] = max(Maxa[nowk], a[i]);
(a[i] < L[nowk]) ? f[i] = a[i] : f[i] = f[a[i]];
// int fa = max(a[i] - lazy[num[i]], 1ll);
// (fa < L[nowk]) ? f[i] = fa : f[i] = f[fa];
}
lazy[nowk] = 0;
return;
}
void update(int l, int r, int x) {
int lk = num[l], rk = num[r];
if (lk == rk) {
for (int i = l;i <= r;i++) a[i] -= x;
renew(lk);
return;
}
for (int i = l;i <= R[lk];i++) a[i] -= x;
renew(lk);
for (int i = lk + 1;i < rk;i++) {
lazy[i] += x;
if (Maxa[i] - lazy[i] >= L[i]) renew(i);
}
for (int i = L[rk];i <= r;i++) a[i] -= x;
renew(rk);
return;
}
int query(int x, int y) {
int xk = num[x], yk = num[y];
while (xk != yk) {
if (x > y) renew(x), x = f[x];
else renew(y), y = f[y];
xk = num[x], yk = num[y];
}
while (x != y) {
if (x == 1 || y == 1) return 1;
if (x < y) y = max(a[y] - lazy[yk], 1);
else x = max(a[x] - lazy[xk], 1);
}
return x;
}
//int query(int x, int y) {
// int xk, yk;
//
// while (HDF_LOVES_YDMY) {
//
// xk = num[x], yk = num[y];
//
// if (x == y) return x;
// if (max(a[x], 1) == y) return y;
// if (max(a[y], 1) == x) return x;
//// if (max(a[y] - lazy[yk], 1ll) == x) return x;
//// if (max(a[x] - lazy[xk], 1ll) == y) return y;
//// if (max(a[y] - lazy[yk], 1) == x) return x;
//// if (max(a[x] - lazy[xk], 1) == y) return y;
// if (x == 1 || y == 1) return 1;
//
//// renewf(min(x, y) - sqrt(n) - 1, max(x, y));
//
// if (xk != yk) (xk < yk) ? (renew(yk), y = f[y]) : (renew(xk), x = f[x]);
// else {
// if (f[x] == f[y]) {
// while (HDF_LOVES_YDMY) {
// if (x == 1 || y == 1) return 1;
// if (x == y) return x;
// int ax = max(a[x] - lazy[xk], 1), ay = max(a[y] - lazy[yk], 1);
// if (ax == ay) return ax;
// else if (x < y) y = ay;
// else x = ax;
//// if (a[x] == a[y]) return a[x];
//// else if (x < y) y = a[y];
//// else x = a[x];
// }
// }
// else {
//// if (Maxa[num[f[x]]] - lazy[num[f[x]]] >= L[num[f[x]]]) renew(num[f[x]]);
//// renew(xk - 1);
// x = f[x], y = f[y];
// }
// }
//
//// if (xk != yk) (xk < yk) ? (renew(yk), y = f[y]) : (renew(xk), x = f[x]);
//// else {
//// renew(xk);
//// if (f[x] == f[y]) {
//// while (HDF_LOVES_YDMY) {
//// if (x == 1 || y == 1) return 1;
//// if (x == y) return x;
//// int ax = max(a[x] - lazy[xk], 1), ay = max(a[y] - lazy[yk], 1);
//// if (ax == ay) return ax;
//// else if (x < y) y = ay;
//// else x = ax;
////// if (a[x] == a[y]) return a[x];
////// else if (x < y) y = a[y];
////// else x = a[x];
//// }
//// }
//// else x = f[x], y = f[y];
//// }
// }
//
//// int xk = num[x], yk = num[y];
//// if (x == 1 || y == 1) return HDF_LOVES_YDMY;
//// while (xk != yk) {
//// if (y > x) renew(yk), y = f[y];
//// else renew(xk), x = f[x];
//// xk = num[x], yk = num[y];
//// }
//// renew(xk);
//// while (x != y) {
//// xk = num[x], yk = num[y];
//// if (x == 1 || y == 1) return HDF_LOVES_YDMY;
//// if (f[x] != f[y]) {
//// x = f[x], y = f[y];
//// renew(xk);
//// continue;
//// }
//// if (x == y) return x;
//// if (x > y) x = a[x];
//// else y = a[y];
//// }
////// return (x != y) ? a[x] : x;
//// return x;
//}
signed main() {
n = read(), m = read();
a[1] = 1;
L[0] = 1, R[0] = 1;num[1] = 0;
for (int i = 2;i <= n;i++) a[i] = read();
init();
while (m--) {
int op = read(), j = read(), k = read(), l;
if (op == 1) l = read(), update(j ^ lastans, k ^ lastans, l ^ lastans);
else lastans = query(j ^ lastans, k ^ lastans), /*printf("%lld", lastans)*/write(lastans), puts("");
}
return 0;
}