結果
問題 |
No.2949 Product on Tree
|
ユーザー |
![]() |
提出日時 | 2024-10-27 18:47:47 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 225 ms / 2,000 ms |
コード長 | 1,233 bytes |
コンパイル時間 | 2,124 ms |
コンパイル使用メモリ | 201,768 KB |
最終ジャッジ日時 | 2025-02-25 00:55:36 |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 3 |
other | AC * 46 |
ソースコード
#include <bits/stdc++.h> #include <atcoder/modint> using namespace std; using ll = long long; using namespace atcoder; using mint = modint998244353; int main(){ cin.tie(nullptr); ios_base::sync_with_stdio(false); //dp(i)=iを根とする部分木での答え ll N, U, V; cin >> N; vector<ll> A(N); vector<vector<ll>> E(N); for (int i=0; i<N; i++) cin >> A[i]; for (int i=0; i<N-1; i++){ cin >> U >> V; U--; V--; E[U].push_back(V); E[V].push_back(U); } mint ans=0, iv=mint(2).inv(); vector<mint> dp(N); auto dfs=[&](auto self, int from, int p=-1)->void{ mint res=0, res2=0; for (auto to : E[from]){ if (to == p) continue; self(self, to, from); res += dp[to]; res2 += dp[to] * dp[to]; dp[from] += dp[to]; } dp[from] += 1; //fromをLCPとする頂点間での答えへの寄与 //prod(i, j)dp[i]dp[j] * A[i] ans += (res*res-res2) * iv * A[from]; dp[from] *= A[from]; //fromを末端とするパスの答えへの寄与 ans += dp[from]-A[from]; }; dfs(dfs, 0); cout << ans.val() << endl; return 0; }