結果

問題 No.1204 お菓子配り-FINAL
コンテスト
ユーザー vjudge1
提出日時 2026-04-11 09:51:12
言語 C++14
(gcc 15.2.0 + boost 1.89.0)
コンパイル:
g++-15 -O2 -lm -std=c++14 -Wuninitialized -DONLINE_JUDGE -o a.out _filename_
実行:
./a.out
結果
WA  
実行時間 -
コード長 5,188 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 731 ms
コンパイル使用メモリ 96,608 KB
実行使用メモリ 7,976 KB
最終ジャッジ日時 2026-04-11 09:51:28
合計ジャッジ時間 14,866 ms
ジャッジサーバーID
(参考情報)
judge3_0 / judge1_1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 105 WA * 25
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

const int MOD = 1000000007;

// ?????
long long power(long long base, long long exp) {
    long long res = 1;
    base %= MOD;
    while (exp > 0) {
        if (exp % 2 == 1) res = (res * base) % MOD;
        base = (base * base) % MOD;
        exp /= 2;
    }
    return res;
}

long long modInverse(long long n) {
    return power(n, MOD - 2);
}

const int MAX = 200005;
long long fact[MAX];
long long invFact[MAX];

// ????????
void precompute() {
    fact[0] = 1;
    invFact[0] = 1;
    for (int i = 1; i < MAX; i++) {
        fact[i] = (fact[i - 1] * i) % MOD;
    }
    invFact[MAX - 1] = modInverse(fact[MAX - 1]);
    for (int i = MAX - 2; i >= 1; i--) {
        invFact[i] = (invFact[i + 1] * (i + 1)) % MOD;
    }
}

// ??????????? l ?????: (l+1)^(l-1) / l!
long long f(long long l) {
    if (l == 0) return 1;
    return power(l + 1, l - 1) * invFact[l] % MOD;
}

// ?? [w^n] F(w)^m ???????
long long get_c(long long m, long long n) {
    if (m == 0) return (n == 0) ? 1 : 0;
    if (n == 0) return 1;
    long long p = power((n + m) % MOD, n - 1);
    long long ans = m % MOD * p % MOD;
    ans = ans * invFact[n] % MOD;
    return ans;
}

int main() {
    // ??IO??
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    precompute();

    long long N, M;
    if (!(cin >> N >> M)) return 0;
    string S;
    cin >> S;

    int c = 0;
    for (char ch : S) {
        if (ch == '-') c++;
    }

    int V = N - M;
    long long ans = 0;

    bool has_o = false;
    for (char ch : S) {
        if (ch == 'o') {
            has_o = true;
            break;
        }
    }

    // ?? 1: S ??????? 'o'
    if (has_o) {
        int first_o = -1, last_o = -1;
        for (int i = 0; i < M; ++i) {
            if (S[i] == 'o') {
                if (first_o == -1) first_o = i;
                last_o = i;
            }
        }

        int a = first_o;
        int b = M - 1 - last_o;

        long long Win = 1;
        int current_dash = 0;
        for (int i = first_o + 1; i <= last_o; ++i) {
            if (S[i] == '-') {
                current_dash++;
            } else {
                Win = Win * f(current_dash) % MOD;
                current_dash = 0;
            }
        }

        vector<long long> Pa(a, 0);
        for (int i = 0; i < a; ++i) Pa[i] = f(i);

        vector<long long> Pb(b, 0);
        for (int i = 0; i < b; ++i) Pb[i] = f(i);

        int degR = max(a, b) - 1;
        vector<long long> R(degR + 1, 0);
        for (int i = 0; i < a; ++i) R[i] = (R[i] + Pa[i]) % MOD;
        for (int i = 0; i < b; ++i) R[i] = (R[i] + Pb[i]) % MOD;

        int degQ = -1;
        vector<long long> Q;
        if (a > 0 && b > 0) {
            degQ = a + b - 2;
            Q.assign(degQ + 1, 0);
            for (int i = 0; i < a; ++i) {
                for (int j = 0; j < b; ++j) {
                    Q[i + j] = (Q[i + j] + Pa[i] * Pb[j]) % MOD;
                }
            }
        }

        for (int k = 0; k <= V; ++k) {
            long long Wk = 0;
            if (k == V) {
                Wk = f(a + V + b) * Win % MOD;
            } else {
                long long T1 = get_c(V - k + 1, k + a + b);
                long long T2 = 0;
                for (int i = 0; i <= degR; ++i) {
                    T2 = (T2 + R[i] * get_c(V - k, k + a + b - i)) % MOD;
                }
                long long T3 = 0;
                if (degQ >= 0) {
                    for (int j = 0; j <= degQ; ++j) {
                        T3 = (T3 + Q[j] * get_c(V - k - 1, k + a + b - j)) % MOD;
                    }
                }
                long long ck = (T1 - T2 + T3) % MOD;
                if (ck < 0) ck += MOD;
                Wk = ck * Win % MOD;
            }

            long long K = c + k;
            long long term = Wk * fact[K] % MOD;
            term = term * power(N, N - K) % MOD;
            ans = (ans + term) % MOD;
        }

    } else {
        // ?? 2: S ???? '-'????????????
        for (int k = 0; k < V; ++k) {
            long long term1_p1 = M * power(M + 1, k + M - 1) % MOD * invFact[k + M - 1] % MOD;
            long long term1_p2 = (M - 1) * power(M + 1, k + M) % MOD * invFact[k + M] % MOD;
            long long term1 = (term1_p1 - term1_p2 + MOD) % MOD;

            long long term2 = 0;
            for (int n = 0; n < M; ++n) {
                long long pn = (n - M + 1 + MOD) % MOD * f(n) % MOD;
                long long v1 = power(M - n, k + M - n) * invFact[k + M - n] % MOD;
                long long v2 = 0;
                if (k + M - n - 1 >= 0) {
                    v2 = power(M - n, k + M - n - 1) * invFact[k + M - n - 1] % MOD;
                }
                long long val = pn * (v1 - v2 + MOD) % MOD;
                term2 = (term2 + val) % MOD;
            }

            long long ck = (term1 - term2 + MOD) % MOD;
            long long K = M + k;
            long long ways = ck * fact[K] % MOD;
            ways = ways * power(N, N - K) % MOD;
            ans = (ans + ways) % MOD;
        }
    }

    ans = ans * (N - M + 1) % MOD;
    cout << ans << "\n";

    return 0;
}
0