提出 #64389607


ソースコード 拡げる

#include <random>
#include <string>
#include <vector>
#include <cassert>
#include <iostream>
#include <algorithm>
using namespace std;

string to_string(const vector<int>& arr) {
	string res = "[";
	for (int i = 0; i < int(arr.size()); i++) {
		if (i != 0) {
			res += ", ";
		}
		res += to_string(arr[i]);
	}
	res += "]";
	return res;
}

struct parade {
	int a, b, l, r;
};

struct query {
	int l, r;
};

class mergesort_tree {
private:
	int size;
	vector<vector<pair<int, uint64_t> > > tsub;
	vector<vector<uint64_t> > txor;
	vector<int> T_;
	vector<uint64_t> H_;
public:
	mergesort_tree(int N, const vector<int>& T, const vector<uint64_t>& H) {
		size = 1 << (N >= 2 ? 32 - __builtin_clz(N - 1) : 0);
		tsub.resize(2 * size);
		for (int i = 0; i < N; i++) {
			tsub[size + i] = {make_pair(T[i], H[i])};
		}
		for (int i = size - 1; i >= 1; i--) {
			tsub[i].resize(tsub[i * 2].size() + tsub[i * 2 + 1].size());
			merge(tsub[i * 2].begin(), tsub[i * 2].end(), tsub[i * 2 + 1].begin(), tsub[i * 2 + 1].end(), tsub[i].begin());
		}
		txor.resize(2 * size);
		for (int i = 1; i < 2 * size; i++) {
			txor[i].resize(tsub[i].size() + 1);
			for (int j = 0; j < int(tsub[i].size()); j++) {
				txor[i][j + 1] = txor[i][j] ^ tsub[i][j].second;
			}
		}
		// for (int i = size - 1; i >= 1; i--) {
		// 	if (tsub[i].size() >= 2) {
		// 		for (int j = 1; j < tsub[i].size(); j++) {
		// 			tsub[i][j].second ^= tsub[i][j - 1].second;
		// 		}
		// 	}
		// }
		T_ = T;
		H_ = H;
	}
	pair<int, uint64_t> query(int l, int r, int d, int u) {
		/*
		int cnt = 0; uint64_t hx = 0;
		for (int i = l; i < r; i++) {
			if (d <= T_[i] && T_[i] < u) {
				cnt++;
				hx ^= H_[i];
			}
		}
		return make_pair(cnt, hx);
		*/
		pair<int, uint64_t> ans = {0, uint64_t(0)};
		auto check = [&](int x) -> void {
			int pd = lower_bound(tsub[x].begin(), tsub[x].end(), make_pair(d, uint64_t(0))) - tsub[x].begin();
			int pu = lower_bound(tsub[x].begin(), tsub[x].end(), make_pair(u, uint64_t(0))) - tsub[x].begin();
			// for (int i = pd; i < pu; i++) {
			// 	ans.first++;
			// 	ans.second ^= tsub[x][i].second;
			// }
			// uint64_t hd = (pd >= 1 ? tsub[x][pd - 1].second : 0);
			// uint64_t hu = (pu >= 1 ? tsub[x][pu - 1].second : 0);
			ans.first += pu - pd;
			ans.second ^= txor[x][pd] ^ txor[x][pu];
		};
		l += size;
		r += size;
		while (l != r) {
			if (l & 1) {
				check(l++);
			}
			if (r & 1) {
				check(--r);
			}
			l /= 2;
			r /= 2;
		}
		return ans;
	};
};

vector<bool> solve_path(int N, int M, int Q, const vector<int>& T, const vector<int>& C, const vector<parade>& P, const vector<query>& qs) {
	// step #1. hashing
	mt19937_64 mt(202503311258);
	vector<uint64_t> hbase(N);
	for (int i = 0; i < N; i++) {
		hbase[i] = mt();
	}
	vector<uint64_t> hc(N);
	for (int i = 0; i < N; i++) {
		hc[i] = hbase[C[i]];
	}

	// step #2. calculate for each parade
	mergesort_tree seg(N, T, hc);
	vector<uint64_t> hparade(M);
	for (int i = 0; i < M; i++) {
		if (P[i].a == P[i].b) {
			hparade[i] = ((P[i].r - P[i].l) % 2 == 0 ? uint64_t(0) : hc[P[i].a]);
		} else {
			pair<int, uint64_t> res1 = seg.query(0, P[i].a + 1, P[i].l, P[i].r);
			pair<int, uint64_t> res2 = seg.query(P[i].b, N, P[i].l, P[i].r);
			pair<int, uint64_t> res3 = seg.query(P[i].a + 1, P[i].b, P[i].l, P[i].r);
			// cerr << "res1: " << res1.first << ' ' << res1.second << endl;
			// cerr << "res2: " << res2.first << ' ' << res2.second << endl;
			// cerr << "res3: " << res3.first << ' ' << res3.second << endl;
			uint64_t h = res3.second;
			if (res1.first & 1) {
				h ^= hc[P[i].a];
			}
			if (res2.first & 1) {
				h ^= hc[P[i].b];
			}
			hparade[i] = h;
		}
	}

	// step #3. prefix sum
	vector<uint64_t> hprefix(M + 1);
	for (int i = 0; i < M; i++) {
		hprefix[i + 1] = hprefix[i] ^ hparade[i];
	}
	vector<uint64_t> hsort = hbase;
	sort(hsort.begin(), hsort.end());

	// step #4. solve
	vector<bool> ans(Q);
	for (int i = 0; i < Q; i++) {
		int l = qs[i].l, r = qs[i].r;
		uint64_t h = hprefix[l] ^ hprefix[r];
		ans[i] = (h == 0 || binary_search(hsort.begin(), hsort.end(), h));
	}

	return ans;
}

vector<bool> solve(int N, int M, int Q, const vector<vector<int> >& G, const vector<int>& C, const vector<parade>& P, const vector<query>& qs) {
	assert(N <= 2000 && M <= 2000);

	// step #1. build tree
	vector<int> par(N, -1), d(N);
	auto build_tree = [&](auto& self, int x, int pre) -> void {
		for (int i : G[x]) {
			if (i != pre) {
				par[i] = x;
				d[i] = d[x] + 1;
				self(self, i, x);
			}
		}
	};
	build_tree(build_tree, 0, -1);

	// step #2. get each "nearest"
	vector<vector<int> > tbl(M, vector<int>(N));
	for (int i = 0; i < M; i++) {
		vector<bool> path(N, false);
		int a = P[i].a, b = P[i].b;
		path[a] = true;
		path[b] = true;
		while (a != b) {
			if (d[a] < d[b]) {
				swap(a, b);
			}
			a = par[a];
			path[a] = true;
		}
		auto dfs = [&](auto& self, int x, int pre, int c) -> void {
			tbl[i][x] = c;
			for (int i : G[x]) {
				if (i != pre) {
					self(self, i, x, c);
				}
			}
		};
		for (int j = 0; j < N; j++) {
			if (path[j]) {
				tbl[i][j] = j;
				for (int k : G[j]) {
					if (!path[k]) {
						dfs(dfs, k, j, j);
					}
				}
			}
		}
	}

	// step #3. hashing
	mt19937_64 mt(202503311258);
	vector<uint64_t> hbase(N);
	for (int i = 0; i < N; i++) {
		hbase[i] = mt();
	}
	vector<uint64_t> hparade(M);
	for (int i = 0; i < M; i++) {
		for (int j = P[i].l; j < P[i].r; j++) {
			hparade[i] ^= hbase[C[tbl[i][j]]];
		}
	}
	vector<uint64_t> hprefix(M + 1);
	for (int i = 0; i < M; i++) {
		hprefix[i + 1] = hprefix[i] ^ hparade[i];
	}
	vector<uint64_t> hsort = hbase;
	sort(hsort.begin(), hsort.end());

	// step #4. solve
	vector<bool> ans(Q);
	for (int i = 0; i < Q; i++) {
		int l = qs[i].l, r = qs[i].r;
		uint64_t h = hprefix[l] ^ hprefix[r];
		ans[i] = (h == 0 || binary_search(hsort.begin(), hsort.end(), h));
	}

	return ans;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);
	int N;
	cin >> N;
	vector<int> A(N - 1), B(N - 1);
	for (int i = 0; i < N - 1; i++) {
		cin >> A[i] >> B[i];
		A[i]--; B[i]--;
	}
	bool is_path = true;
	for (int i = 0; i < N - 2; i++) {
		is_path = is_path && (B[i] == A[i + 1]);
	}
	vector<int> C(N);
	for (int i = 0; i < N; i++) {
		cin >> C[i];
		C[i]--;
	}
	int M;
	cin >> M;
	vector<parade> P(M);
	for (int i = 0; i < M; i++) {
		cin >> P[i].a >> P[i].b >> P[i].l >> P[i].r;
		P[i].a--; P[i].b--; P[i].l--;
	}
	int Q;
	cin >> Q;
	vector<query> qs(Q);
	for (int i = 0; i < Q; i++) {
		cin >> qs[i].l >> qs[i].r;
		qs[i].l--;
	}
	if (is_path) {
		vector<int> T = A;
		T.push_back(B[N - 2]);
		vector<int> TINV(N);
		for (int i = 0; i < N; i++) {
			TINV[T[i]] = i;
		}
		for (parade& p : P) {
			p.a = TINV[p.a];
			p.b = TINV[p.b];
			if (p.a > p.b) {
				swap(p.a, p.b);
			}
		}
		vector<int> TC(N);
		for (int i = 0; i < N; i++) {
			TC[i] = C[T[i]];
		}
		vector<bool> ans = solve_path(N, M, Q, T, TC, P, qs);
		for (int i = 0; i < Q; i++) {
			cout << (ans[i] ? "Yes" : "No") << '\n';
		}
	} else {
		vector<vector<int> > G(N);
		for (int i = 0; i < N - 1; i++) {
			G[A[i]].push_back(B[i]);
			G[B[i]].push_back(A[i]);
		}
		vector<bool> ans = solve(N, M, Q, G, C, P, qs);
		for (int i = 0; i < Q; i++) {
			cout << (ans[i] ? "Yes" : "No") << '\n';
		}
	}
	return 0;
}

提出情報

提出日時
問題 C - Can Make Palindrome
ユーザ square1001
言語 C++ 20 (gcc 12.2)
得点 50
コード長 7542 Byte
結果 RE
実行時間 1819 ms
メモリ 154520 KiB

ジャッジ結果

セット名 Sample Subtask1 Subtask2 Subtask3 Subtask4 Subtask5 Subtask6 Subtask7 Subtask8
得点 / 配点 0 / 0 5 / 5 5 / 5 5 / 5 5 / 5 20 / 20 10 / 10 0 / 40 0 / 10
結果
AC × 4
AC × 7
AC × 13
AC × 21
AC × 9
AC × 18
AC × 27
AC × 31
RE × 7
AC × 43
RE × 21
セット名 テストケース
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt
Subtask1 01_subtask1_00.txt, 01_subtask1_01.txt, 01_subtask1_02.txt, 01_subtask1_03.txt, 01_subtask1_04.txt, 01_subtask1_05.txt, 00_sample_00.txt
Subtask2 01_subtask1_00.txt, 01_subtask1_01.txt, 01_subtask1_02.txt, 01_subtask1_03.txt, 01_subtask1_04.txt, 01_subtask1_05.txt, 02_subtask2_00.txt, 02_subtask2_01.txt, 02_subtask2_02.txt, 02_subtask2_03.txt, 02_subtask2_04.txt, 02_subtask2_05.txt, 00_sample_00.txt
Subtask3 01_subtask1_00.txt, 01_subtask1_01.txt, 01_subtask1_02.txt, 01_subtask1_03.txt, 01_subtask1_04.txt, 01_subtask1_05.txt, 02_subtask2_00.txt, 02_subtask2_01.txt, 02_subtask2_02.txt, 02_subtask2_03.txt, 02_subtask2_04.txt, 02_subtask2_05.txt, 03_subtask3_00.txt, 03_subtask3_01.txt, 03_subtask3_02.txt, 03_subtask3_03.txt, 03_subtask3_04.txt, 03_subtask3_05.txt, 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
Subtask4 04_subtask4_00.txt, 04_subtask4_01.txt, 04_subtask4_02.txt, 04_subtask4_03.txt, 04_subtask4_04.txt, 01_subtask1_03.txt, 02_subtask2_03.txt, 03_subtask3_03.txt, 00_sample_01.txt
Subtask5 04_subtask4_00.txt, 04_subtask4_01.txt, 04_subtask4_02.txt, 04_subtask4_03.txt, 04_subtask4_04.txt, 01_subtask1_03.txt, 02_subtask2_03.txt, 03_subtask3_03.txt, 05_subtask5_00.txt, 05_subtask5_01.txt, 05_subtask5_02.txt, 05_subtask5_03.txt, 05_subtask5_04.txt, 01_subtask1_04.txt, 02_subtask2_04.txt, 03_subtask3_04.txt, 00_sample_01.txt, 00_sample_02.txt
Subtask6 04_subtask4_00.txt, 04_subtask4_01.txt, 04_subtask4_02.txt, 04_subtask4_03.txt, 04_subtask4_04.txt, 01_subtask1_03.txt, 02_subtask2_03.txt, 03_subtask3_03.txt, 05_subtask5_00.txt, 05_subtask5_01.txt, 05_subtask5_02.txt, 05_subtask5_03.txt, 05_subtask5_04.txt, 01_subtask1_04.txt, 02_subtask2_04.txt, 03_subtask3_04.txt, 06_subtask6_00.txt, 06_subtask6_01.txt, 06_subtask6_02.txt, 06_subtask6_03.txt, 06_subtask6_04.txt, 06_subtask6_05.txt, 06_subtask6_06.txt, 06_subtask6_07.txt, 06_subtask6_08.txt, 00_sample_01.txt, 00_sample_02.txt
Subtask7 01_subtask1_00.txt, 01_subtask1_01.txt, 01_subtask1_02.txt, 01_subtask1_03.txt, 01_subtask1_04.txt, 01_subtask1_05.txt, 02_subtask2_00.txt, 02_subtask2_01.txt, 02_subtask2_02.txt, 02_subtask2_03.txt, 02_subtask2_04.txt, 02_subtask2_05.txt, 03_subtask3_00.txt, 03_subtask3_01.txt, 03_subtask3_02.txt, 03_subtask3_03.txt, 03_subtask3_04.txt, 03_subtask3_05.txt, 04_subtask4_00.txt, 04_subtask4_01.txt, 04_subtask4_02.txt, 04_subtask4_03.txt, 04_subtask4_04.txt, 05_subtask5_00.txt, 05_subtask5_01.txt, 05_subtask5_02.txt, 05_subtask5_03.txt, 05_subtask5_04.txt, 07_subtask7_00.txt, 07_subtask7_01.txt, 07_subtask7_02.txt, 07_subtask7_03.txt, 07_subtask7_04.txt, 07_subtask7_05.txt, 07_subtask7_06.txt, 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
Subtask8 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 00_sample_03.txt, 01_subtask1_00.txt, 01_subtask1_01.txt, 01_subtask1_02.txt, 01_subtask1_03.txt, 01_subtask1_04.txt, 01_subtask1_05.txt, 02_subtask2_00.txt, 02_subtask2_01.txt, 02_subtask2_02.txt, 02_subtask2_03.txt, 02_subtask2_04.txt, 02_subtask2_05.txt, 03_subtask3_00.txt, 03_subtask3_01.txt, 03_subtask3_02.txt, 03_subtask3_03.txt, 03_subtask3_04.txt, 03_subtask3_05.txt, 04_subtask4_00.txt, 04_subtask4_01.txt, 04_subtask4_02.txt, 04_subtask4_03.txt, 04_subtask4_04.txt, 05_subtask5_00.txt, 05_subtask5_01.txt, 05_subtask5_02.txt, 05_subtask5_03.txt, 05_subtask5_04.txt, 06_subtask6_00.txt, 06_subtask6_01.txt, 06_subtask6_02.txt, 06_subtask6_03.txt, 06_subtask6_04.txt, 06_subtask6_05.txt, 06_subtask6_06.txt, 06_subtask6_07.txt, 06_subtask6_08.txt, 07_subtask7_00.txt, 07_subtask7_01.txt, 07_subtask7_02.txt, 07_subtask7_03.txt, 07_subtask7_04.txt, 07_subtask7_05.txt, 07_subtask7_06.txt, 08_subtask8_00.txt, 08_subtask8_01.txt, 08_subtask8_02.txt, 08_subtask8_03.txt, 08_subtask8_04.txt, 08_subtask8_05.txt, 08_subtask8_06.txt, 08_subtask8_07.txt, 08_subtask8_08.txt, 08_subtask8_09.txt, 08_subtask8_10.txt, 08_subtask8_11.txt, 08_subtask8_12.txt, 08_subtask8_13.txt, 08_subtask8_14.txt, 08_subtask8_15.txt
ケース名 結果 実行時間 メモリ
00_sample_00.txt AC 1 ms 3468 KiB
00_sample_01.txt AC 1 ms 3492 KiB
00_sample_02.txt AC 1 ms 3392 KiB
00_sample_03.txt AC 1 ms 3420 KiB
01_subtask1_00.txt AC 2 ms 3576 KiB
01_subtask1_01.txt AC 2 ms 3636 KiB
01_subtask1_02.txt AC 1 ms 3568 KiB
01_subtask1_03.txt AC 1 ms 3736 KiB
01_subtask1_04.txt AC 1 ms 3696 KiB
01_subtask1_05.txt AC 1 ms 3628 KiB
02_subtask2_00.txt AC 62 ms 19128 KiB
02_subtask2_01.txt AC 59 ms 19172 KiB
02_subtask2_02.txt AC 2 ms 3992 KiB
02_subtask2_03.txt AC 4 ms 4500 KiB
02_subtask2_04.txt AC 5 ms 4572 KiB
02_subtask2_05.txt AC 21 ms 19180 KiB
03_subtask3_00.txt AC 86 ms 20728 KiB
03_subtask3_01.txt AC 86 ms 20744 KiB
03_subtask3_02.txt AC 21 ms 5512 KiB
03_subtask3_03.txt AC 27 ms 5892 KiB
03_subtask3_04.txt AC 28 ms 5984 KiB
03_subtask3_05.txt AC 44 ms 20728 KiB
04_subtask4_00.txt AC 849 ms 154360 KiB
04_subtask4_01.txt AC 851 ms 154436 KiB
04_subtask4_02.txt AC 843 ms 154396 KiB
04_subtask4_03.txt AC 427 ms 122456 KiB
04_subtask4_04.txt AC 275 ms 59936 KiB
05_subtask5_00.txt AC 1758 ms 154340 KiB
05_subtask5_01.txt AC 1757 ms 154512 KiB
05_subtask5_02.txt AC 1745 ms 154272 KiB
05_subtask5_03.txt AC 585 ms 65304 KiB
05_subtask5_04.txt AC 564 ms 25980 KiB
06_subtask6_00.txt AC 1798 ms 154364 KiB
06_subtask6_01.txt AC 1790 ms 154520 KiB
06_subtask6_02.txt AC 1800 ms 154352 KiB
06_subtask6_03.txt AC 519 ms 116424 KiB
06_subtask6_04.txt AC 284 ms 10216 KiB
06_subtask6_05.txt AC 1212 ms 154276 KiB
06_subtask6_06.txt AC 1221 ms 154276 KiB
06_subtask6_07.txt AC 1819 ms 154336 KiB
06_subtask6_08.txt AC 1798 ms 154436 KiB
07_subtask7_00.txt RE 168 ms 21584 KiB
07_subtask7_01.txt RE 168 ms 21528 KiB
07_subtask7_02.txt RE 168 ms 21484 KiB
07_subtask7_03.txt RE 126 ms 16104 KiB
07_subtask7_04.txt RE 125 ms 15484 KiB
07_subtask7_05.txt RE 152 ms 22348 KiB
07_subtask7_06.txt RE 99 ms 11676 KiB
08_subtask8_00.txt RE 174 ms 21480 KiB
08_subtask8_01.txt RE 173 ms 21564 KiB
08_subtask8_02.txt RE 173 ms 21540 KiB
08_subtask8_03.txt RE 173 ms 21576 KiB
08_subtask8_04.txt RE 173 ms 21520 KiB
08_subtask8_05.txt RE 173 ms 21516 KiB
08_subtask8_06.txt RE 133 ms 15388 KiB
08_subtask8_07.txt RE 112 ms 14256 KiB
08_subtask8_08.txt AC 873 ms 154432 KiB
08_subtask8_09.txt AC 177 ms 72704 KiB
08_subtask8_10.txt RE 155 ms 22240 KiB
08_subtask8_11.txt RE 128 ms 18600 KiB
08_subtask8_12.txt RE 175 ms 21640 KiB
08_subtask8_13.txt RE 173 ms 21564 KiB
08_subtask8_14.txt RE 168 ms 21640 KiB
08_subtask8_15.txt RE 169 ms 21568 KiB