萌新刚学 OI,简单分块题 WA+死循环 求调
查看原帖
萌新刚学 OI,简单分块题 WA+死循环 求调
377873
EricWan楼主2025/7/23 21:28

跑得还是蛮快的,https://www.luogu.com.cn/record/226412111,出现了死循环(一个点)和 WA 一堆点。

感觉是边界问题(大分块边界我就没打对过),求调。

悬三个小号的关注。

504 行开始是代码,前面的东西是 debug 库和快读快写。大概不是快读快写的问题。

#include <bits/stdc++.h>
using namespace std;
#define variable_name(x) #x
#define vdebug(x) variable_name(x) << " = " << x
#define pdebug(x) "*" << variable_name(x) << " = " << *(x)
#define all(x) (x).begin(), (x).end()
#define adebug(a, b, c) #a << "[" << (b) << "..." << (c) << "] = " << vector<typename decay<decltype(*((a) + (b)))>::type>((a) + (b), (a) + (c) + 1)
namespace quick_io {
	#if defined(__GNUC__) && defined(__SIZEOF_INT128__)
		#ifndef quick_io_can_use_int128
			#define quick_io_can_use_int128
			#define mark_can_use_in_quick_io
		#endif
	#endif
	#ifdef quick_io_can_use_int128
		#define quick_io_int_length_limit 128
		#define quick_io_int_radix_type size_t
		#define quick_io_length_type size_t
		bool is_digit[128];
		quick_io_int_radix_type cur_int_radix = 0;
		char __quick_io_d2c(size_t a) {
			if (a <= 9) {
				return '0' + a;
			} else if (a <= 35) {
				return 'A' + a - 10;
			} else {
				return 'a' + a - 36;
			}
		}
		size_t __quick_io_c2d(char a) {
			if (a >= '0' && a <= '9') {
				return a - '0';
			} else if (a >= 'A' && a <= 'Z') {
				return a - 'A' + 10;
			} else /*if (a >= 'a' && a <= 'z')*/ {
				return a - 'a' + 36;
			}
		}
		struct quick_io_change_int_radix {
			quick_io_change_int_radix(quick_io_int_radix_type new_int_radix) {
				if (cur_int_radix == new_int_radix) return;
				cur_int_radix = new_int_radix;
				memset(is_digit, 0, sizeof(is_digit));
				for (size_t i = 0; i < new_int_radix; i++) {
					is_digit[size_t(__quick_io_d2c(i))] = true;
				}
			}
		} set_radix(10);
		// Weak robustness, maybe can't be correct if the input format changes
		// Very slow functions
		ostream &operator<<(ostream &A, __int128 b) {
			char a[128], k = 0;
			memset(a, 0, sizeof(a));
			quick_io_length_type pos = 0;
			unsigned __int128 b_ = b;
			if (b < 0) k = -1, b_ = -b;
			while (b_) {
				a[pos++] = __quick_io_d2c(b_ % cur_int_radix);
				b_ /= cur_int_radix;
			}
			if (!~k) {
				a[pos++] = '-';
			}
			if (!pos) {
				a[pos++] = '0';
			}
			reverse(a, a + pos);
			return A << a;
		}
		istream &operator>>(istream &A, __int128 &b) {
			int k = 1;
			char c = A.get();
			b = 0;
			while (c != '-' && c != '+' && !is_digit[size_t(c)]) {
				c = A.get();
			}
			if (c == '-') {
				k = -1;
				c = A.get();
			} else if (c == '+') {
				c = A.get();
			}
			while (is_digit[size_t(c)]) {
				b = b * cur_int_radix + __quick_io_c2d(c);
				c = A.get();
			}
			if (!~k) b = -b;
			A.unget();
			return A;
		}
		ostream &operator<<(ostream &A, unsigned __int128 b) {
			char a[128];
			memset(a, 0, sizeof(a));
			quick_io_length_type pos = 0;
			while (b) {
				a[pos++] = __quick_io_d2c(b % cur_int_radix);
				b /= cur_int_radix;
			}
			if (!pos) {
				a[pos++] = '0';
			}
			reverse(a, a + pos);
			return A << a;
		}
		istream &operator>>(istream &A, unsigned __int128 &b) {
			char c = A.get();
			b = 0;
			while (!is_digit[size_t(c)]) {
				c = A.get();
			}
			while (is_digit[size_t(c)]) {
				b = b * cur_int_radix + __quick_io_c2d(c);
				c = A.get();
			}
			A.unget();
			return A;
		}
		#ifdef mark_can_use_in_quick_io
			#undef quick_io_can_use_int128
			#undef mark_can_use_in_quick_io
		#endif
	#endif
	template<typename T>
	ostream &operator<<(ostream &A, const vector<T> &b);
	template<typename T>
	ostream &operator<<(ostream &A, const deque<T> &b);
	template<typename T1, typename T2>
	ostream &operator<<(ostream &A, const pair<T1, T2> &b);
	template<typename T>
	ostream &operator<<(ostream &A, const set<T> &b);
	template<typename T>
	ostream &operator<<(ostream &A, const multiset<T> &b);
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const map<T, T2> &b);
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const multimap<T, T2> &b);
	template<typename T>
	ostream &operator<<(ostream &A, const unordered_set<T> &b);
	template<typename T>
	ostream &operator<<(ostream &A, const unordered_multiset<T> &b);
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const unordered_map<T, T2> &b);
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const unordered_multimap<T, T2> &b);
	template<typename T>
	ostream &operator<<(ostream &A, const vector<T> &b) {
		A << "[";
		for (size_t i = 0; i + 1 < b.size(); i++) {
			A << b[i] << ",";
		}
		if (b.size()) {
			A << b[b.size() - 1];
		}
		A << "]";
		return A;
	}
	template<typename T>
	ostream &operator<<(ostream &A, const deque<T> &b) {
		A << "[";
		for (size_t i = 0; i + 1 < b.size(); i++) {
			A << b[i] << ",";
		}
		if (b.size()) {
			A << b[b.size() - 1];
		}
		A << "]";
		return A;
	}
	template<typename T1, typename T2>
	ostream &operator<<(ostream &A, const pair<T1, T2> &b) {
		return A << '(' << b.first << ',' << b.second << ')';
	}
	template<typename T>
	ostream &operator<<(ostream &A, const set<T> &b) {
		typename set<T>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T>
	ostream &operator<<(ostream &A, const multiset<T> &b) {
		typename multiset<T>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const map<T, T2> &b) {
		typename map<T, T2>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const multimap<T, T2> &b) {
		typename multimap<T, T2>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T>
	ostream &operator<<(ostream &A, const unordered_set<T> &b) {
		typename unordered_set<T>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T>
	ostream &operator<<(ostream &A, const unordered_multiset<T> &b) {
		typename unordered_multiset<T>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const unordered_multimap<T, T2> &b) {
		typename unordered_multimap<T, T2>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T, typename T2>
	ostream &operator<<(ostream &A, const unordered_map<T, T2> &b) {
		typename unordered_map<T, T2>::const_iterator i = b.begin(), e = b.end();
		A << "{";
		while (i != e) {
			A << *i;
			i++;
			if (i != e) {
				A << ",";
			}
		}
		return A << "}";
	}
	template<typename T1, typename T2>
	istream &operator>>(istream &A, pair<T1, T2> &b) {
		return A >> b.first >> b.second;
	}
	template<typename T>
	void print_array(T b, T e, string s = " ") {
		while (b != e) {
			cout << *b;
			b++;
			if (b != e) {
				cout << s;
			}
		}
	}
	template<typename T>
	void auto_print(T &b, size_t n, string s = " ") {
		for (size_t i = 1; i < n; i++) {
			cout << b[i] << s;
		}
		cout << b[n];
	}
	template<typename T>
	void auto_print(T &b, string s = " ") {
		for (auto i : b) {
			cout << i << s;
		}
	}
	template<typename T>
	void print_n(T b, size_t n, string s = " ") {
		if (n == 0) return;
		cout << *b;
		for (size_t i = 1; i < n; i++) {
			b++;
			cout << s << *b;
		}
	}
	template<typename T>
	void read_array(T b, T e) {
		while (b != e) {
			cin >> *b;
			b++;
		}
	}
	template<typename T>
	void auto_read(T &b, size_t n) {
		for (size_t i = 1; i <= n; i++) {
			cin >> b[i];
		}
	}
	template<typename T>
	void read_n(T b, size_t n) { // untested
		cin >> *b;
		for (size_t i = 1; i < n; i++) {
			b++;
			cin >> *b;
		}
	}
	template <typename T>
	string to_string(const T& value) {
		ostringstream oss;
		oss << value;
		return oss.str();
	}
	template <typename Array>
	string array_debug_impl(const Array& a) {
		return "";
	}
	template <typename Array, typename First, typename... Rest>
	string array_debug_impl(const Array& a, First first, Rest... rest) {
		string current = "[" + to_string(first) + "]";
		string next = array_debug_impl(a, rest...);
		return current + next;
	}
	template <typename T>
	decltype(auto) get_nested(T&& first) {
		return forward<T>(first);
	}
	template <typename T, typename U, typename... Args>
	decltype(auto) get_nested(T&& first, U&& second, Args&&... args) {
		return get_nested(forward<T>(first)[forward<U>(second)], forward<Args>(args)...);
	}
	template <typename Array, typename... Args>
	string array_debug(const Array& a, Args... args) {
		string indices_str = array_debug_impl(a, args...);
		ostringstream value_oss;
		value_oss << get_nested(a, args...);
		return indices_str + " = " + value_oss.str();
	}
	ostream &operator<<(ostream &a, ostream &b) {
		return b;
	}
	#if 1 // use debug macros
		#define aedebug(first, ...) #first << array_debug(first, __VA_ARGS__)
		#define spc << " " <<
	#endif
	#undef quick_io_int_length_limit
	#undef quick_io_int_radix_type
	#undef quick_io_length_type
}
using namespace quick_io;
// #define fast_ios_buffer_enough
// #define fast_is_buffer_enough
// #define fast_os_buffer_enough
#define fast_ios_only_int
// #define fast_is_only_int
// #define fast_os_only_int
#ifdef fast_ios_buffer_enough
	#define fast_is_buffer_enough
	#define fast_os_buffer_enough
#endif
#ifdef fast_ios_only_int
	#define fast_is_only_int
	#define fast_os_only_int
#endif
template<size_t buffer_size = 65536>
struct fast_reader_t {
	// short, int, long, long long, __int128
	// unsigned short, int, long, long long, __int128
    // very safe if there are no overflow
	size_t pos;
	unsigned char c;
	unsigned char in_buffer[buffer_size];
	inline fast_reader_t() : pos(0), c(EOF) {
		for (size_t i = fread(in_buffer, 1, buffer_size, stdin); i < buffer_size; i++) {
			in_buffer[i] = EOF;
		}
	}
	inline unsigned char &get() {
		#ifndef fast_is_buffer_enough
		if (pos < buffer_size) {
		#endif
			return c = in_buffer[pos++];
		#ifndef fast_is_buffer_enough
		}
		for (size_t i = fread(in_buffer, 1, buffer_size, stdin); i < buffer_size; i++) {
			in_buffer[i] = EOF;
		}
		return c = in_buffer[(pos = 0)++];
		#endif
	}
	inline void unget() {
		pos--;
	}
	template<typename T>
	typename enable_if<is_integral<T>::value && is_unsigned<T>::value, fast_reader_t&>::type
	inline operator>>(T &x) {
		x = 0;
		while ((c = get()) < '0' || c > '9');
		do {
			x = (x << 3) + (x << 1) + (c ^ '0');
		} while ((c = get()) >= '0' && c <= '9');
		#ifndef fast_is_only_int
		unget();
		#endif
		return *this;
	}
	template<typename T>
	typename enable_if<is_integral<T>::value && is_signed<T>::value, fast_reader_t&>::type
	inline operator>>(T &x) {
		typename make_unsigned<T>::type x_ = 0;
		bool sign = false;
		while (((c = get()) < '0' || c > '9') && c != '-' && c != '+');
		if (c == '-') {
			sign = true;
			c = get();
		} else if (c == '+') {
			c = get();
		}
		do {
			x_ = (x_ << 3) + (x_ << 1) + (c ^ '0');
		} while ((c = get()) >= '0' && c <= '9');
		x = x_;
		if (sign) {
			x = -x;
		}
		#ifndef fast_is_only_int
		unget();
		#endif
		return *this;
	}
};
template<size_t buffer_size = 65536>
struct fast_writer_t {
	// short, int, long, long long, __int128
	// unsigned short, int, long, long long, __int128
	size_t pos;
	unsigned char out_buffer[buffer_size];
	inline fast_writer_t() : pos(0) {}
	inline ~fast_writer_t() {
		if (pos) {
			flush();
		}
	}
	inline void flush() {
		__builtin_fwrite(out_buffer, 1, pos, stdout);
		pos = 0;
	}
	inline void put(unsigned char c) {
		out_buffer[pos++] = c;
		#ifndef fast_os_buffer_enough
		if (pos == buffer_size) {
			flush();
		}
		#endif
	}
	template<typename T>
	typename enable_if<is_integral<T>::value && is_unsigned<T>::value, fast_writer_t&>::type
	inline operator<<(const T &x) {
		if (x >= T(10)) {
			*this << x / T(10);
		}
		put('0' ^ x % T(10));
		return *this;
	}
	template<typename T>
	typename enable_if<is_integral<T>::value && is_signed<T>::value, fast_writer_t&>::type
	inline operator<<(const T &x) {
		if (x >= T(0)) {
			return *this << (typename make_unsigned<T>::type)x;
		} else {
			put('-');
			return *this << (typename make_unsigned<T>::type)(-x);
		}
	}
};
fast_reader_t<> fast_reader;
fast_writer_t<> fast_writer;
#define K 500
#define block_L(x) (((x) - 1) / K * K + 1)
#define block_R(x) min(n, (((x) - 1) / K + 1) * K)
#define block_id(x) (((x) - 1) / K)
#define block_id2L(x) ((x) * K + 1)
#define block_id2R(x) min(n, ((x) + 1) * K)
int n, q, a[1000005], nxt[1000005];
bool all_out[1000005];
int tag[1000005];
int small_jump(int x)
{
	return max(1, a[x] - tag[block_id(x)]);
}
int big_jump(int x)
{
	return max(0, all_out[block_id(x)] ? a[x] - tag[block_id(x)] : nxt[x]);
}
void build(int L, int R) {
	// cout << "build(" << L << "," << R << ")" << endl;
	int bid = block_id(L);
	all_out[bid] = 1;
	for (int i = L; i <= R; i++)
	{
		if (a[i] < L)
		{
			nxt[i] = a[i];
		}
		else
		{
			all_out[bid] = 0;
			nxt[i] = nxt[a[i]];
		}
	}
	tag[bid] = 0;
}
signed main() {
	fast_reader >> n >> q;
	for (int i = 2; i <= n; i++) {
		fast_reader >> a[i];
	}
	for (int L = 1, R = K; L <= n; L += K, R += K) {
		build(L, min(n, R));
	}
	// cout << adebug(a, 1, n) << endl;
	// cout << adebug(nxt, 1, n) << endl;
	int x, y, k, op, lastans = 0;
	while (q--) {
		fast_reader >> op >> x >> y;
		x ^= lastans;
		y ^= lastans;
		// cout << op << " " << x << " " << y << endl;
		if (op == 2) {
			// cout << adebug(a, 1, n) << endl;
			// cout << adebug(nxt, 1, n) << endl;
			while (true)
			{
				int bjx = big_jump(x);
				int bjy = big_jump(y);
				// cout << x << "," << y << " -> " << bjx << "," << bjy << endl;
				if (bjx > bjy)
				{
					x = bjx;
				}
				else if (bjy < bjx)
				{
					y = bjy;
				}
				else
				{
					break;
				}
			}
			// cout << x << " " << y << endl;
			while (x != y)
			{
				// cout << x << " " << y << " -> " << small_jump(x) << " " << small_jump(y) << endl;
				int jx = small_jump(x);
				int jy = small_jump(y);
				if (jx >= jy)
				{
					x = jx;
				}
				if (jy >= jx)
				{
					y = jy;
				}
			}
			// cout << x << endl;
			fast_writer << (lastans = x);
			fast_writer.put('\n');
		} else {
			fast_reader >> k;
			k ^= lastans;
			int lb = block_id(x);
			int rb = block_id(y);
			if (lb == rb)
			{
				// cout << "in one block" << endl;
				if (all_out[lb] && tag[lb])
				{
					for (int i = block_id2L(lb), i_e = block_id2R(lb); i <= i_e; i++)
					{
						a[i] -= tag[lb];
						if (a[i] < 1)
						{
							a[i] = 1;
						}
					}
				}
				for (int i = x; i <= y; i++)
				{
					a[i] -= k;
					if (a[i] < 1)
					{
						a[i] = 1;
					}
				}
				build(block_id2L(lb), block_id2R(lb));
				continue;
			}
			for (int b_id = lb + 1; b_id < rb; b_id++)
			{
				if (all_out[b_id])
				{
					tag[b_id] += k;
				}
				else
				{
					int i_b = block_id2L(b_id);
					int i_e = block_id2R(b_id);
					// cout << i_b << "~" << i_e << " rebuild" << endl;
					for (int i = i_b; i <= i_e; i++)
					{
						a[i] -= k;
						if (a[i] < 1)
						{
							a[i] = 1;
						}
					}
					build(i_b, i_e);
				}
			}
			int i_e = block_id2R(lb);
			for (int i = x; i <= i_e; i++)
			{
				a[i] -= k;
				if (a[i] < 1)
				{
					a[i] = 1;
				}
			}
			build(block_id2L(lb), i_e);
			for (int i = block_id2L(rb); i <= y; i++)
			{
				a[i] -= k;
				if (a[i] < 1)
				{
					a[i] = 1;
				}
			}
			build(block_id2L(rb), block_id2R(lb));
		}
	}
	return 0;
}
2025/7/23 21:28
加载中...