結果

問題 No.1769 Don't Stop the Game
ユーザー polylogKpolylogK
提出日時 2021-10-29 22:40:59
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
TLE  
実行時間 -
コード長 3,247 bytes
コンパイル時間 1,591 ms
コンパイル使用メモリ 96,348 KB
実行使用メモリ 24,004 KB
最終ジャッジ日時 2024-06-29 17:59:59
合計ジャッジ時間 26,258 ms
ジャッジサーバーID
(参考情報)
judge4 / judge3
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
10,624 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 1 ms
5,376 KB
testcase_03 AC 4 ms
5,376 KB
testcase_04 AC 3 ms
5,376 KB
testcase_05 AC 5 ms
5,376 KB
testcase_06 AC 4 ms
5,376 KB
testcase_07 AC 6 ms
5,376 KB
testcase_08 AC 1,994 ms
14,604 KB
testcase_09 AC 1,573 ms
12,068 KB
testcase_10 AC 2,440 ms
18,452 KB
testcase_11 AC 1,213 ms
11,496 KB
testcase_12 AC 1,128 ms
17,228 KB
testcase_13 AC 1,249 ms
17,476 KB
testcase_14 AC 1,553 ms
17,476 KB
testcase_15 AC 2,145 ms
17,472 KB
testcase_16 AC 2,631 ms
17,468 KB
testcase_17 TLE -
testcase_18 TLE -
testcase_19 TLE -
testcase_20 -- -
testcase_21 -- -
testcase_22 -- -
testcase_23 -- -
testcase_24 -- -
testcase_25 -- -
testcase_26 -- -
testcase_27 -- -
testcase_28 -- -
testcase_29 -- -
testcase_30 -- -
権限があれば一括ダウンロードができます

ソースコード

diff #

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

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

#define NDEBUG

using i64 = long long;

bool deleted[200'000];
int size[200'000];

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);

		auto solve = [&](auto&& solve, int root, int all) -> void {
			int centroid_tmp = -1;
			auto calc_size = [&](auto&& dfs, int v, int par) -> int {
				size[v] = 1;
				int tmp = v;
				for(int id: g[v]) {
					int to = v ^ a[id] ^ b[id];
					if(to == par or deleted[to]) continue;

					int sub_size = dfs(dfs, to, v);
					if(sub_size * 2 > all) tmp = -1;
					size[v] += sub_size;
				}
				if(2 * (all - size[v]) > all) tmp = -1;
				if(tmp != -1) centroid_tmp = tmp;
				return size[v];
			}; calc_size(calc_size, root, -1);
			int centroid = centroid_tmp;
			calc_size(calc_size, centroid, -1);

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

					{ // counting 0-xor paths
						std::set<int> xor_path; xor_path.insert(0);
						auto dfs = [&](auto&& dfs, int v, int par, int xor_val) -> void {
							if(loop and xor_path.count(xor_val)) { // [u-centroid]
								answer -= size[centroid] - size[to];
							}

							bool append = false;
							if(!xor_path.count(xor_val)) {
								answer -= map[xor_val];

								xor_path.insert(xor_val);
								append = true;
							}

							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]);
							};

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

								xor_path.insert(xor_val);
								append = true;
							}

							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]);
							};

							if(append) {
								xor_path.erase(xor_val);
							}
						}; dfs(dfs, to, centroid, c[id]);
					}
				}

				if(loop) answer -= map[0];
				reverse(begin(g[centroid]), end(g[centroid]));
			}

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

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

		}; solve(solve, start, g.size());

		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