#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD = 1000000007;
struct Matrix{
int n, m;
int mat[2][2];
Matrix(){}
Matrix(int n, int m): n(n), m(m){
for(int i=0; i<n; i++) for(int j=0; j<m; j++) mat[i][j] = 0;
}
Matrix operator*(const Matrix &r)const{
assert(m == r.n);
Matrix ret (n, r.m);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
for(int k=0; k<r.m; k++){
ret.mat[i][k] += mat[i][j] * r.mat[j][k];
ret.mat[i][k] %= MOD;
}
}
}
return ret;
}
};
ll mpow(ll x, ll y){
if(!y) return 1;
if(y%2) return mpow(x, y-1) * x % MOD;
ll tmp = mpow(x, y/2);
return tmp*tmp%MOD;
}
Matrix BasicMatrix(int n, int m){
Matrix mat (n, m);
assert(n==m);
for(int i=0; i<n; i++) mat.mat[i][i] = 1;
return mat;
}
Matrix mpow(Matrix x, ll y){
if(!y) return BasicMatrix(x.n, x.m);
if(y&1) return mpow(x, y-1) * x;
Matrix tmp = mpow(x, y/2);
return tmp * tmp;
}
ll n;
ll k;
vector<int> link[1002];
ll mat[1002][1002];
ll depth[1002];
ll group[1002], groupCnt[2];
ll ans;
ll DP[2][1002];
ll find1[1002], find2[1002];
void dfs(int x, int p, int r){
if(r==1){
group[x] = depth[x]%2;
groupCnt[group[x]]++;
}
for(auto y: link[x]){
if(y==p) continue;
depth[y] = depth[x] + 1;
dfs(y, x, r);
if(!mat[r][y]) mat[r][x] = 1;
}
}
int dfsFind(int x, int p, int dp, int r){ /// 무조건 지나야 하는 상대 차례 점 개수 찾기
if(dp % 2 == 0){ /// my turn
int cnt = 0;
for(auto y: link[x]){
if(y!=p && !mat[r][y]) cnt++;
}
if(cnt > 1) return 0;
assert(cnt == 1);
for(auto y: link[x]){
if(y!=p && !mat[r][y]) return dfsFind(y, x, dp+1, r);
}
exit(1);
}
else{ /// your turn
int ret = 1;
for(auto y: link[x]){
if(y==p) continue;
ret += dfsFind(y, x, dp+1, r);
}
return ret;
}
}
int dfsFind2(int x, int p, int dp, int r){
if(dp % 2 == 0){ /// my turn
int ret = 1;
for(auto y: link[x]){
if(y==p) continue;
ret += dfsFind2(y, x, dp+1, r);
}
return ret;
}
else{ /// your turn
int cnt = 0;
for(auto y: link[x]){
if(y!=p && !mat[r][y]) cnt++;
}
if(cnt > 1) return 0;
assert(cnt == 1);
for(auto y: link[x]){
if(y!=p && !mat[r][y]) return dfsFind2(y, x, dp+1, r);
}
exit(1);
}
}
int main(){
scanf("%lld %lld", &n, &k);
for(int i=1; i<n; i++){
int x, y;
scanf("%d %d", &x, &y);
link[x].push_back(y);
link[y].push_back(x);
}
// for(int i=n; i>=1; i--){
// for(int x=0; x<=n+1; x++) depth[x] = DP[x] = 0;
// dfs(i), DProot[i] = DP[i];
// }
// for(int i=1; i<=n; i++) printf("%d ", DProot[i]);
for(int i=1; i<=n; i++){
dfs(i, -1, i);
if(mat[i][i]) find1[i] = groupCnt[!group[i]] - dfsFind(i, -1, 0, i);
else find2[i] = dfsFind2(i, -1, 0, i);
DP[0][i] = mat[i][i];
}
Matrix first (1, 2);
first.mat[0][0] = first.mat[0][1] = 0;
for(int i=1; i<=n; i++){
if(mat[i][i]) first.mat[0][0]++;
else first.mat[0][1]++;
}
Matrix multiplier (2, 2); /// 0: WIN, 1: LOSE
for(int i=1; i<=n; i++){
if(mat[i][i]){
multiplier.mat[0][0] = (multiplier.mat[0][0] + n) % MOD;
multiplier.mat[1][0] = (multiplier.mat[1][0] + groupCnt[group[i]]) % MOD;
multiplier.mat[1][0] = (multiplier.mat[1][0] + find1[i]) % MOD;
multiplier.mat[0][1] = (multiplier.mat[0][1] + n*n - n)%MOD;
multiplier.mat[1][1] = (multiplier.mat[0][1] + n*n - groupCnt[group[i]] - find1[i])%MOD;
}
else{
multiplier.mat[1][0] = (multiplier.mat[1][0] + find2[i]) % MOD;
multiplier.mat[0][1] = (multiplier.mat[0][1] + n*n) % MOD;
multiplier.mat[1][1] = (multiplier.mat[1][0] + n*n - find2[i]) % MOD;
}
}
multiplier = mpow(multiplier, k-1);
first = first * multiplier;
ll Wsum = first.mat[0][0], Lsum = first.mat[0][1];
ll ans = 0;
if(mat[1][1]){
ans = (Wsum * n + groupCnt[group[1]] * Lsum + find1[1] * Lsum) % MOD;
}
else ans = find2[1] * Lsum % MOD;
// int b = turn%2;
//
// /// 전처리
// ll Wsum = 0; /// 이기는 가짓수
// for(int i=1; i<=n; i++) Wsum = (Wsum + DP[!b][i]) % MOD;
// ll Lsum = (mpow(n, 2*turn-1) - Wsum + MOD) % MOD; /// 지는 가짓수
//
// /// 실제 계산
// for(int i=1; i<=n; i++){
// DP[b][i] = 0;
// if(mat[i][i]){ /// 여기서 시작하면 이기는 경우
// /// ? -> W
// DP[b][i] = (DP[b][i] + Wsum * n) % MOD;
// /// my turn -> L
// DP[b][i] = (DP[b][i] + groupCnt[group[i]] * Lsum) % MOD;
// /// your turn -> L
// DP[b][i] = (DP[b][i] + find1[i] * Lsum) % MOD;
// }
// else{
// DP[b][i] = (DP[b][i] + find2[i] * Lsum) % MOD;
// }
// }
// }
printf("%lld", ans);
}
Compilation message
startrek.cpp: In function 'int main()':
startrek.cpp:123:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
123 | scanf("%lld %lld", &n, &k);
| ~~~~~^~~~~~~~~~~~~~~~~~~~~
startrek.cpp:126:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
126 | scanf("%d %d", &x, &y);
| ~~~~~^~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
340 KB |
Output is correct |
2 |
Incorrect |
20 ms |
8172 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Incorrect |
1 ms |
340 KB |
Output isn't correct |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
328 KB |
Output is correct |
2 |
Correct |
1 ms |
724 KB |
Output is correct |
3 |
Correct |
1 ms |
848 KB |
Output is correct |
4 |
Correct |
1 ms |
724 KB |
Output is correct |
5 |
Correct |
1 ms |
844 KB |
Output is correct |
6 |
Correct |
1 ms |
724 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
328 KB |
Output is correct |
2 |
Correct |
1 ms |
724 KB |
Output is correct |
3 |
Correct |
1 ms |
848 KB |
Output is correct |
4 |
Correct |
1 ms |
724 KB |
Output is correct |
5 |
Correct |
1 ms |
844 KB |
Output is correct |
6 |
Correct |
1 ms |
724 KB |
Output is correct |
7 |
Correct |
27 ms |
8264 KB |
Output is correct |
8 |
Correct |
33 ms |
8220 KB |
Output is correct |
9 |
Correct |
20 ms |
8144 KB |
Output is correct |
10 |
Correct |
19 ms |
8224 KB |
Output is correct |
11 |
Correct |
23 ms |
8192 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
328 KB |
Output is correct |
2 |
Correct |
1 ms |
724 KB |
Output is correct |
3 |
Correct |
1 ms |
848 KB |
Output is correct |
4 |
Correct |
1 ms |
724 KB |
Output is correct |
5 |
Correct |
1 ms |
844 KB |
Output is correct |
6 |
Correct |
1 ms |
724 KB |
Output is correct |
7 |
Correct |
27 ms |
8264 KB |
Output is correct |
8 |
Correct |
33 ms |
8220 KB |
Output is correct |
9 |
Correct |
20 ms |
8144 KB |
Output is correct |
10 |
Correct |
19 ms |
8224 KB |
Output is correct |
11 |
Correct |
23 ms |
8192 KB |
Output is correct |
12 |
Runtime error |
1 ms |
468 KB |
Execution killed with signal 11 |
13 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
328 KB |
Output is correct |
2 |
Correct |
1 ms |
724 KB |
Output is correct |
3 |
Correct |
1 ms |
848 KB |
Output is correct |
4 |
Correct |
1 ms |
724 KB |
Output is correct |
5 |
Correct |
1 ms |
844 KB |
Output is correct |
6 |
Correct |
1 ms |
724 KB |
Output is correct |
7 |
Correct |
27 ms |
8264 KB |
Output is correct |
8 |
Correct |
33 ms |
8220 KB |
Output is correct |
9 |
Correct |
20 ms |
8144 KB |
Output is correct |
10 |
Correct |
19 ms |
8224 KB |
Output is correct |
11 |
Correct |
23 ms |
8192 KB |
Output is correct |
12 |
Correct |
1 ms |
340 KB |
Output is correct |
13 |
Incorrect |
17 ms |
8148 KB |
Output isn't correct |
14 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
328 KB |
Output is correct |
2 |
Correct |
1 ms |
724 KB |
Output is correct |
3 |
Correct |
1 ms |
848 KB |
Output is correct |
4 |
Correct |
1 ms |
724 KB |
Output is correct |
5 |
Correct |
1 ms |
844 KB |
Output is correct |
6 |
Correct |
1 ms |
724 KB |
Output is correct |
7 |
Correct |
27 ms |
8264 KB |
Output is correct |
8 |
Correct |
33 ms |
8220 KB |
Output is correct |
9 |
Correct |
20 ms |
8144 KB |
Output is correct |
10 |
Correct |
19 ms |
8224 KB |
Output is correct |
11 |
Correct |
23 ms |
8192 KB |
Output is correct |
12 |
Runtime error |
1 ms |
468 KB |
Execution killed with signal 11 |
13 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
340 KB |
Output is correct |
2 |
Incorrect |
20 ms |
8172 KB |
Output isn't correct |
3 |
Halted |
0 ms |
0 KB |
- |