This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <bits/stdc++.h>
using namespace std;
constexpr int MOD = 1e9 + 7;
struct Mat {
int mat[2][2] = {};
int* operator[](const int &idx) { return mat[idx]; }
Mat operator*(Mat &o) {
Mat ans;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
for (int k = 0; k < 2; k++)
(ans[i][k] += ((long long)mat[i][j] * o[j][k]) % MOD) %= MOD;
return ans;
}
Mat operator^(const long long &exp) {
Mat ans = { .mat = {{1, 0}, {0, 1}} };
Mat base = *this;
for (long long e = exp; e; e >>= 1) {
if (e & 1) ans = base * ans;
base = base * base;
}
return ans;
}
};
struct Info {
bool win;
int forceable;
void merge_child(const Info &ch) {
if (win) {
if (!ch.win) {
forceable = 0;
}
} else {
if (ch.win) {
forceable += ch.forceable;
} else {
win = true;
forceable = ch.forceable;
}
}
}
Info() : win(false), forceable(1) { }
};
int solve(int N, long long D, const vector<vector<int>> &adj) {
vector<Info> dp(N);
int w = 0, l = 0;
Mat trans;
auto dfs1 = [&](auto &&dfs1, int node, int par = -1) -> void {
dp[node] = Info();
for (auto child: adj[node]) {
if (child == par) continue;
dfs1(dfs1, child, node);
dp[node].merge_child(dp[child]);
}
};
auto dfs2 = [&](auto &&dfs2, int node, int par = -1) -> void {
if (par != -1) {
dp[par] = Info();
for (auto ch: adj[par])
if (ch != node)
dp[par].merge_child(dp[ch]);
dp[node].merge_child(dp[par]);
}
if (dp[node].win) {
w++;
(trans[0][0] += dp[node].forceable) %= MOD;
(trans[1][0] += N - dp[node].forceable) %= MOD;
(trans[1][1] += N) %= MOD;
} else {
l++;
(trans[0][0] += N - dp[node].forceable) %= MOD;
(trans[1][0] += dp[node].forceable) %= MOD;
(trans[0][1] += N) %= MOD;
}
for (auto ch: adj[node])
if (ch != par)
dfs2(dfs2, ch, node);
if (par != -1) {
dp[node] = Info();
for (auto ch: adj[node])
if (ch != par)
dp[node].merge_child(dp[ch]);
dp[par].merge_child(dp[node]);
}
};
dfs1(dfs1, 0);
dfs2(dfs2, 0);
Mat final = trans ^ (D - 1);
int w_tot = ((long long)w * final[1][1] + (long long)l * final[1][0]) % MOD;
int l_tot = ((long long)w * final[0][1] + (long long)l * final[0][0]) % MOD;
long long ans = 0;
if (dp[0].win) {
(ans += (long long)(N - dp[0].forceable) * l_tot) %= MOD;
(ans += (long long)N * w_tot) %= MOD;
} else {
(ans += (long long)dp[0].forceable * l_tot) %= MOD;
}
return ans;
}
int main() {
ios_base::sync_with_stdio(false); cin.tie(nullptr);
int N; cin >> N;
long long D; cin >> D;
vector<vector<int>> adj(N);
for (int i = 0; i < N - 1; i++) {
int u, v; cin >> u >> v;
adj[u - 1].push_back(v - 1);
adj[v - 1].push_back(u - 1);
}
cout << solve(N, D, adj) << '\n';
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |