結果
| 問題 |
No.1769 Don't Stop the Game
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2021-10-29 20:23:12 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,937 bytes |
| コンパイル時間 | 9,039 ms |
| コンパイル使用メモリ | 126,476 KB |
| 最終ジャッジ日時 | 2025-01-25 08:18:37 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 WA * 1 |
| other | AC * 2 WA * 15 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) -> void {
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] * 2 > size[root]) return dfs(dfs, to, v);
}
return v;
};
int centroid = get_centroid(get_centroid, root, -1);
deleted[centroid] = true;
#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
calc_size(calc_size, centroid, -1);
{ // unroll-looping
std::map<int, int> map;
for(int i = 0; i < g[centroid].size(); i++) {
int id = g[centroid][i];
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 {
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]);
}
}
{ // unroll-looping
std::map<int, int> map;
for(int i = (int)g[centroid].size() - 1; i >= 0; i--) {
int id = g[centroid][i];
int to = centroid ^ a[id] ^ b[id];
if(deleted[to]) continue;
solve(solve, to);
{ // 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(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]);
}
}
answer -= map[0];
}
}
deleted[centroid] = false;
}; 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());
}