結果
| 問題 | No.1769 Don't Stop the Game |
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-10-29 22:40:59 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.89.0) |
| 結果 |
TLE
|
| 実行時間 | - |
| コード長 | 3,247 bytes |
| 記録 | |
| コンパイル時間 | 7,051 ms |
| コンパイル使用メモリ | 118,220 KB |
| 最終ジャッジ日時 | 2025-01-25 09:16:09 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 17 TLE * 11 |
ソースコード
#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());
}