Submission #585813

# Submission time Handle Problem Language Result Execution time Memory
585813 2022-06-29T11:28:53 Z 79brue Star Trek (CEOI20_startrek) C++17
23 / 100
33 ms 8264 KB
#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);
      |         ~~~~~^~~~~~~~~~~~~~~~~
# Verdict Execution time Memory 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 -
# Verdict Execution time Memory Grader output
1 Incorrect 1 ms 340 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory 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
# Verdict Execution time Memory 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
# Verdict Execution time Memory 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 -
# Verdict Execution time Memory 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 -
# Verdict Execution time Memory 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 -
# Verdict Execution time Memory 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 -