20ptsWA+TLE求条
查看原帖
20ptsWA+TLE求条
564941
天野星河楼主2024/8/11 14:18

rt

#include <bits/stdc++.h>
using namespace std;
const int N = 4e5 + 10, mod = 1e9 + 7, BL = 700;
int n, m;
int a[N];
int len, num;
int L[BL], R[BL], in[N], father[N];
int parent[N];
int chg[N];
long long tag[BL];

inline void build() {
	len = sqrt(n) + 1;
	num = (n + len - 1) / len;
	for (int i = 1; i <= num; i++) {
		L[i] = (i - 1) * len + 1;
		R[i] = i * len;
	}
	R[num] = n;
	for (int i = 1; i <= num; i++)
		for (int j = L[i]; j <= R[i]; j++)
			in[j] = i;
}

inline bool chk(int x) { return chg[x] <= len; }

inline void modify(int i) {
	if (chk(in[i]))
		parent[i] = in[i] == in[father[i]] ? parent[father[i]] : father[i];
}

inline void modify(int i, int k) {
	if (!chk(i))
		tag[i] = min(tag[i] + k, (long long)n);
	else {
		for (int j = L[in[i]]; j <= R[in[i]]; j++) {
			father[j] = max(1, father[j] - k);
			modify(j);
		}
	}
}

inline void modify(int l, int r, int k) {
	for (int i = l; i <= r; i++)
		father[i] = max(1, father[i] - k);
	for (int i = l; i <= R[in[r]]; i++)
		modify(i);
}

inline void update(int l, int r, int k) {
	if (in[l] == in[r])
		modify(l, r, k);
	else {
		modify(l, R[in[l]], k);
		modify(L[in[r]], r, k);
		for (int i = in[l] + 1; i < in[r]; i++) {
			modify(i, k);
			chg[i]++;
		}
	}
}

inline int pa(int x) { return chk(in[x]) ? parent[x] : max(1ll, father[x] - tag[in[x]]); }
inline int fa(int x) { return chk(in[x]) ? father[x] : max(1ll, father[x] - tag[in[x]]); }

inline int query(int x, int y) {
	while (x != y) {
		int px = pa(x), py = pa(y);
		if (in[px] != in[py]) {
			if (in[px] < in[py])
				y = py;
			else
				x = px;
		} else if (px != py) {
			if (px < py)
				y = py;
			else
				x = px;
		} else {
			if (x < y)
				y = fa(y);
			else
				x = fa(x);
		}
	}
	return x;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin >> n >> m;
	build();
	for (int i = 2; i <= n; i++)
		cin >> father[i];
	for (int i = 2; i <= n; i++)
		parent[i] = in[i] == in[father[i]] ? parent[father[i]] : father[i];
	int last = 0;
	while (m--) {
		int op, l, r, k;
		cin >> op >> l >> r;
		l ^= last;
		r ^= last;
		if (op == 1) {
			cin >> k;
			k ^= last;
			update(l, r, k);
		} else if (op == 2)
			cout << (last = query(l, r)) << '\n';
	}
}
2024/8/11 14:18
加载中...