結果

問題 No.1769 Don't Stop the Game
ユーザー polylogKpolylogK
提出日時 2021-10-29 03:29:14
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 3,561 bytes
コンパイル時間 1,243 ms
コンパイル使用メモリ 86,416 KB
実行使用メモリ 21,440 KB
最終ジャッジ日時 2023-09-12 04:50:40
合計ジャッジ時間 11,908 ms
ジャッジサーバーID
(参考情報)
judge15 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,388 KB
testcase_01 AC 2 ms
4,376 KB
testcase_02 AC 2 ms
4,376 KB
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 TLE -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 TLE -
testcase_17 TLE -
testcase_18 -- -
testcase_19 -- -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

// #include <testlib.h>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <map>

#define NDEBUG

using i64 = long long;

struct solve_t {
	std::vector<std::vector<int>> g;
	std::vector<int> a, b, c;

	solve_t(int n): g(n) {}
	void add_edge(int u, int v, int w) {
		g[u].push_back(a.size());
		g[v].push_back(a.size());
		a.push_back(u);
		b.push_back(v);
		c.push_back(w);
	}

	i64 solve(int start = 0) {
		i64 answer = (i64)g.size() * ((i64)g.size() - 1);

		std::vector<bool> deleted(g.size());
		auto solve = [&](auto&& solve, int root) -> void {
			static std::vector<int> size(g.size());
			auto calc_size = [&](auto&& dfs, int v, int par) -> int {
				size[v] = 1;
				for(int id: g[v]) {
					int to = v ^ a[id] ^ b[id];
					if(to == par or deleted[to]) continue;

					size[v] += dfs(dfs, to, v);
				}
				return size[v];
			}; calc_size(calc_size, root, -1);

			auto get_centroid = [&](auto&& dfs, int v, int par) -> int {
				for(int id: g[v]) {
					int to = v ^ a[id] ^ b[id];
					if(to == par or deleted[to]) continue;

					if(size[to] > size[root] / 2) return dfs(dfs, to, v);
				}
				return v;
			};
			int centroid = get_centroid(get_centroid, root, -1);

			// 分割統治
			deleted[centroid] = true;
			for(int id: g[centroid]) {
				int to = centroid ^ a[id] ^ b[id];
				if(deleted[to]) continue;

				solve(solve, to);
			}
			deleted[centroid] = false;

			calc_size(calc_size, centroid, -1);

			#ifndef NDEBUG
			printf("root: %d\n", root + 1);
			printf("centroid: %d\n", centroid + 1);
			for(auto e: deleted) printf("%d ", (int)e); puts("");
			for(auto e: size) printf("%d ", e); puts("");
			for(int id: g[centroid]) if(!deleted[a[id] ^ b[id] ^ centroid])
				printf("%d ", (a[id] ^ b[id] ^ centroid) + 1); puts("");
			#endif

			// [u-centroid-v]
			for(int loop = 0; loop < 2; loop++) {
				std::map<int, i64> map;
				for(int id: g[centroid]) {
					int to = centroid ^ a[id] ^ b[id];
					if(deleted[to]) continue;

					{ // counting 0-xor paths
						std::map<int, int> xor_path; xor_path[0] = 1;
						auto dfs = [&](auto&& dfs, int v, int par, int xor_val) -> void {
							if(loop and xor_path[xor_val]) answer -= size[centroid] - size[to];
							if(!xor_path[xor_val]) answer -= map[xor_val];

							xor_path[xor_val] += 1;
							for(int id: g[v]) {
								int to = v ^ a[id] ^ b[id];
								if(to == par or deleted[to]) continue;

								dfs(dfs, to, v, xor_val ^ c[id]);
							};
							xor_path[xor_val] -= 1;
						}; dfs(dfs, to, centroid, c[id]);
					}
					{ // mapping path xors
						std::map<int, int> xor_path;
						auto dfs = [&](auto&& dfs, int v, int par, int xor_val) -> void {
							if(!xor_path.count(xor_val)) map[xor_val] += size[v];

							xor_path[xor_val] += 1;
							for(int id: g[v]) {
								int to = v ^ a[id] ^ b[id];
								if(to == par or deleted[to]) continue;

								dfs(dfs, to, v, xor_val ^ c[id]);
							};
							xor_path[xor_val] -= 1;
						}; dfs(dfs, to, centroid, c[id]);
					}
				}

				#ifndef NDEBUG
				printf("loop(%d): ", loop);
				for(auto [p, q]: map) printf("(%d: %lld), ", p, q); puts("");
				printf("%lld\n", answer);
				#endif

				if(loop) answer -= map[0];
				reverse(begin(g[centroid]), end(g[centroid]));
			}
			#ifndef NDEBUG
			puts("");
			#endif
		}; solve(solve, start);

		return answer;
	}
};

int main() {
	int n; scanf("%d", &n);

	solve_t solver(n);
	for(int i = 0; i < n - 1; i++) {
		int u, v, w; scanf("%d%d%d", &u, &v, &w);

		solver.add_edge(u - 1, v - 1, w);
	}
	printf("%lld\n", solver.solve());
}
0