답안 #585628

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
585628 2022-06-29T06:44:34 Z 박상훈(#8384) Star Trek (CEOI20_startrek) C++17
7 / 100
2 ms 2644 KB
#include <bits/stdc++.h>

typedef long long ll;
using namespace std;
const int MOD = 1e9+7;
vector<int> adj[100100];
bool _win[100100], _win_pa[100100], _win_root[100100], ok[100100];
ll S[100100];

void dfs1(int s, int pa = -1){
    int wcnt = 0, lcnt = 0;
    for (auto &v:adj[s]) if (v!=pa){
        dfs1(v, s);
        if (_win[v]) wcnt++;
        else lcnt++;
    }

    if (!lcnt) _win[s] = 0;
    else _win[s] = 1;

    if (lcnt<=1) ok[s] = 1;
}

void dfs2(int s, int pa = -1){
    int wcnt = 0, lcnt = 0;
    for (auto &v:adj[s]) if (v!=pa){
        if (_win[v]) wcnt++;
        else lcnt++;
    }
    if (pa!=-1){
        if (_win_pa[s]) wcnt++;
        else lcnt++;
    }

    for (auto &v:adj[s]) if (v!=pa){
        if (_win[v]) wcnt--;
        else lcnt--;

        if (!lcnt) _win_pa[v] = 0;
        else _win_pa[v] = 1;

        if (_win[v]) wcnt++;
        else lcnt++;
    }

    if (!lcnt) _win_root[s] = 0;
    else _win_root[s] = 1;

    for (auto &v:adj[s]) if (v!=pa) dfs2(v, s);
}

int lscnt[100100], lscnt_pa[100100], lscnt_root[100100];
void dfs3(int s, int pa = -1){
    if (!_win[s]) lscnt[s]++;

    int lcnt = 0, wcnt = 0;
    for (auto &v:adj[s]) if (v!=pa){
        dfs3(v, s);
        if (!_win[v]) lcnt++;
        else wcnt++;
    }

    for (auto &v:adj[s]) if (v!=pa){
        if (lcnt==1 && !_win[v]) lscnt[s] += lscnt[v];
        else if (lcnt==0) lscnt[s] += lscnt[v];
    }
}

void dfs4(int s, int pa = -1){
    ///count
    int wcnt = 0, lcnt = 0, sum = 0;
    vector<int> L;
    for (auto &v:adj[s]) if (v!=pa){
        if (_win[v]) wcnt++;
        else lcnt++;
        sum += lscnt[v];

        if (!_win[v]) L.push_back(v);
    }
    if (pa!=-1){
        if (_win_pa[s]) wcnt++;
        else lcnt++;
        sum += lscnt_pa[s];
    }

    ///calc pa
    for (auto &v:adj[s]) if (v!=pa){
        if (_win[v]) wcnt--;
        else lcnt--;
        sum -= lscnt[v];

        if (!lcnt) lscnt_pa[v] = sum+1;
        else if (lcnt==1){
            if (pa!=-1 && !_win_pa[s]) lscnt_pa[v] = lscnt_pa[s];
            else{
                if (L[0]!=v) lscnt_pa[v] = lscnt[L[0]];
                else lscnt_pa[v] = lscnt[L[1]];
            }
        }

        if (_win[v]) wcnt++;
        else lcnt++;
        sum += lscnt[v];
    }

    ///calc root
    if (!lcnt) lscnt_root[s] = sum+1;
    else if (lcnt==1){
        if (pa!=-1 && !_win_pa[s]) lscnt_root[s] = lscnt_pa[s];
        else lscnt_root[s] = lscnt[L[0]];
    }

    for (auto &v:adj[s]) if (v!=pa) dfs4(v, s);
}

ll pw(ll a, ll e){
    if (!e) return 1;
    ll ret = pw(a, e/2);
    if (e&1) return ret*ret%MOD*a%MOD;
    return ret*ret%MOD;
}

int main(){
    int n;
    ll d;
    scanf("%d %lld", &n, &d);
    if (n==2) {printf("%lld\n", pw(4, d)); return 0;}

    for (int i=1;i<=n-1;i++){
        int x, y;
        scanf("%d %d", &x, &y);
        adj[x].push_back(y);
        adj[y].push_back(x);
    }

    dfs1(1);
    dfs2(1);
    dfs3(1);
    dfs4(1);

    /*
    for (int i=1;i<=n;i++) printf("%d ", _win[i]); printf("\n");
    for (int i=1;i<=n;i++) printf("%d ", _win_pa[i]); printf("\n");
    for (int i=1;i<=n;i++) printf("%d ", _win_root[i]); printf("\n");
    for (int i=1;i<=n;i++) printf("%d ", ok[i]); printf("\n");
    */

    ll ans = 0, T = 0, L = 0;
    for (int i=1;i<=n;i++){
        if (_win[i]) T += lscnt_root[i];
        else T -= lscnt_root[i], L++;

        if (T>=MOD) T -= MOD;
        if (T<0) T += MOD;
    }

    S[0] = L;
    for (int i=1;i<=d;i++){
        S[i] = (pw(n, (i-1)*2) * L % MOD + T * S[i-1] % MOD) % MOD;
    }

    if (_win[1]) ans = (pw(n, d*2) + MOD) - (lscnt_root[1] * S[d-1] % MOD);
    else ans = lscnt_root[1] * S[d-1] % MOD;
    ans %= MOD;

    printf("%lld\n", ans);

    return 0;
}

/*
int lcnt = 0;
    for (int i=1;i<=n;i++) if (!_win_root[i]) lcnt++;

    ll ans = 0;
    if (_win[1]) ans = (ll)n*n - (ll)lscnt[1] * lcnt;
    else ans = (ll)lscnt[1] * lcnt;
    ans %= MOD;

    printf("%lld\n", ans);
*/

Compilation message

startrek.cpp: In function 'int main()':
startrek.cpp:126:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  126 |     scanf("%d %lld", &n, &d);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~
startrek.cpp:131:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  131 |         scanf("%d %d", &x, &y);
      |         ~~~~~^~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Incorrect 2 ms 2644 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Correct 1 ms 2644 KB Output is correct
3 Correct 2 ms 2644 KB Output is correct
4 Correct 2 ms 2644 KB Output is correct
5 Correct 2 ms 2644 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2644 KB Output is correct
2 Incorrect 1 ms 2644 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2644 KB Output is correct
2 Incorrect 1 ms 2644 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2644 KB Output is correct
2 Incorrect 1 ms 2644 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2644 KB Output is correct
2 Incorrect 1 ms 2644 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 2644 KB Output is correct
2 Incorrect 1 ms 2644 KB Output isn't correct
3 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Incorrect 2 ms 2644 KB Output isn't correct
3 Halted 0 ms 0 KB -