結果
| 問題 |
No.3373 Partial Complement Tree
|
| コンテスト | |
| ユーザー |
champignon
|
| 提出日時 | 2025-11-21 22:25:26 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 3,367 bytes |
| コンパイル時間 | 3,378 ms |
| コンパイル使用メモリ | 291,880 KB |
| 実行使用メモリ | 68,924 KB |
| 最終ジャッジ日時 | 2025-11-21 22:25:35 |
| 合計ジャッジ時間 | 7,823 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 21 WA * 3 |
ソースコード
#include<bits/stdc++.h>
using namespace std;
#define rep(i, l, n) for(int i = int(l); i < int(n); i++)
#define ll long long
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
template<class T> bool chmin(T &a, T b) {if(a > b) {a = b; return true;} return false;}
template<class T> bool chmax(T &a, T b) {if(a < b) {a = b; return true;} return false;}
template<class T> using spq = priority_queue<T, vector<T>, greater<T>>;
// bool -> Yes/No
string answer(bool b) {return b ? "Yes" : "No";}
void fix(int k) {cout << fixed << setprecision(k);}
const int inf = 2e9;
const long long INF = 2e18;
const long double eps = 1e-12;
const long double pi = acos(-1);
int dx[] = {0, -1, 0, 1, -1, -1, 1, 1}, dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
// verify : https://atcoder.jp/contests/abc428/submissions/70542879
// 全方位木dp
template<class S,
S(*merge)(S a, S b),
S(*add_root)(S x, int v),
S(*id)()>
struct Rerooting {
int n; S unit;
std::vector<std::vector<S>> dp;
std::vector<S> ans;
std::vector<std::vector<int>> g;
Rerooting(int N) : n(N) {
unit = id();
dp.resize(N); ans.assign(N, unit);
g.resize(N);
}
void add_edge(int a, int b) {
assert(0 <= a && a < n);
assert(0 <= b && b < n);
g[a].emplace_back(b);
g[b].emplace_back(a);
}
std::vector<S> build() {
dfs(0);
bfs(0, unit);
return ans;
}
S dfs(int v, int par = -1) {
S x = unit;
int m = g[v].size();
dp[v].assign(m, unit);
for(int i = 0; i < m; i++) {
int u = g[v][i];
if(u == par) continue;
dp[v][i] = dfs(u, v);
x = merge(x, dp[v][i]);
}
return add_root(x, v);
}
void bfs(int v, const S &p_val, int par = -1) {
int m = g[v].size();
for(int i = 0; i < m; i++) {
if(g[v][i] == par) dp[v][i] = p_val;
}
std::vector<S> right_values(m + 1, unit);
for(int i = m - 1; i >= 0; i--) {
right_values[i] = merge(right_values[i + 1], dp[v][i]);
}
ans[v] = add_root(right_values[0], v);
S last = unit, cur = unit;
for(int i = 0; i < m; i++) {
last = cur; cur = merge(last, dp[v][i]);
int u = g[v][i];
if(u == par) continue;
bfs(u, add_root(merge(last, right_values[i + 1]), v), v);
}
}
};
struct S {
array<int, 4> cnt;
S() {rep(i, 0, 4) cnt[i] = 0;}
};
S merge(S a, S b) {
S ret;
rep(i, 0, 4) ret.cnt[i] = a.cnt[i] + b.cnt[i];
return ret;
}
S add_root(S x, int v) {
x.cnt[3] = x.cnt[2];
x.cnt[2] = x.cnt[1];
x.cnt[1] = x.cnt[0];
x.cnt[0] = 1;
return x;
}
S id() {return S();}
int n;
void main_program() {
cin >> n;
Rerooting<S, merge, add_root, id> tree_dp(n);
rep(i, 1, n) {
int u, v; cin >> u >> v;
tree_dp.add_edge(--u, --v);
}
long ans = 0;
for(S res : tree_dp.build()) {
ans += res.cnt[3];
//cout << res.cnt[0] << " " << res.cnt[1] << " " << res.cnt[2] << " " << res.cnt[3] << "\n";
}
cout << (ans >> 1) << "\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1;
cin >> T;
while(T--) {
main_program();
}
}
champignon