死循环求调
查看原帖
死循环求调
167697
BartAllen楼主2025/1/29 10:50
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e5 + 5;
const int M = 1e3 + 5;

int n, q, len, tot, a[N], b[N], L[M], R[M], cnt[M], tag[M], pos[N];

void init() {
	len = sqrt(n), tot = (n + 1) / len - 1;
	for (int i = 1; i <= tot; i++)
		L[i] = (i - 1) * len + 1, R[i] = min(n, L[i] + len - 1);
	for (int i = 1; i <= tot; i++)
		for (int j = L[i]; j <= R[i]; j++) pos[j] = i;
}

void change(int l, int r, int x) {
	if (pos[l] == pos[r]) {
		for (int i = l; i <= r; i++) a[i] = max(a[i] - x, 1ll);
		for (int i = l; i <= R[pos[l]]; i++)
			if (cnt[pos[i]] <= len) b[i] = (pos[i] == pos[a[i]] ? b[a[i]] : a[i]);
		return;
	}
	for (int i = l; i <= R[pos[l]]; i++) a[i] = max(a[i] - x, 1ll);
	for (int i = l; i <= R[pos[l]]; i++)
		if (cnt[pos[i]] <= len) b[i] = (pos[i] == pos[a[i]] ? b[a[i]] : a[i]);

	for (int i = L[pos[r]]; i <= r; i++) a[i] = max(a[i] - x, 1ll);
	for (int i = L[pos[r]]; i <= R[pos[r]]; i++)
		if (cnt[pos[i]] <= len) b[i] = (pos[i] == pos[a[i]] ? b[a[i]] : a[i]);

	for (int i = pos[l] + 1; i < pos[r]; i++) {
		if (cnt[i] > len) {
			tag[i] = min(tag[i] + x, n), cnt[i]++;
			continue;
		}
		for (int j = L[i]; j <= R[i]; j++) {
			a[j] = max(a[j] - x, 1ll);
			if (cnt[i] <= len) b[j] = (i == pos[a[j]] ? b[a[j]] : a[j]);
		}
		cnt[i]++;
	}
}

int aska(int x) {
	return (cnt[pos[x]] <= len ? a[x] : max(a[x] - tag[pos[x]], 1ll));
}

int askb(int x) {
	return (cnt[pos[x]] <= len ? b[x] : max(a[x] - tag[pos[x]], 1ll));
}

int asklca(int x, int y) {
	while (x != y) {
		int bx = askb(x), by = askb(y);
		if (pos[bx] != pos[by]) {
			if (pos[bx] < pos[by]) y = by;
			else x = bx;
		}
		else if (bx != by) {
			if (bx < by) y = by;
			else x = bx;
		}
		else {
			if (x > y) x = aska(x);
			else y = aska(y);
		}
	}
	return x;
}

signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> q;
	a[1] = b[1] = 1;
	for (int i = 2; i <= n; i++) cin >> a[i];
	init();
	while (q--) {
		int opt, l, r, x; cin >> opt >> l >> r;
		switch (opt) {
			case 1:
				cin >> x; change(l, r, x);
				for (int i = 1; i <= n; i++) cout << a[i] << " ";
				cout << endl;
				break;
			case 2:
				cout << asklca(l, r) << endl;
		}
	}
	return 0;
}
2025/1/29 10:50
加载中...