Submission #61843132


Source Code Expand

#include <bits/stdc++.h>
using namespace std;
using ll=long long;
#define rep(i,a,b) for (int i=(int)(a);i<(int)(b);i++)
#define all(p) p.begin(),p.end()
#include <atcoder/modint>
using mint = atcoder::modint;

namespace po167{
template<class T>
struct Binomial{
    std::vector<T> fact_vec, fact_inv_vec;
    void extend(int m = -1){
        int n = fact_vec.size();
        if (m == -1) m = n * 2;
        if (n >= m) return;
        fact_vec.resize(m);
        fact_inv_vec.resize(m);
        for (int i = n; i < m; i++){
            fact_vec[i] = fact_vec[i - 1] * T(i);
        }
        fact_inv_vec[m - 1] = T(1) / fact_vec[m - 1];
        for (int i = m - 1; i > n; i--){
            fact_inv_vec[i - 1] = fact_inv_vec[i] * T(i);
        }
    }
    Binomial(int MAX = 0){
        fact_vec.resize(1, T(1));
        fact_inv_vec.resize(1, T(1));
        extend(MAX + 1);
    }

    T fact(int i){
        if (i < 0) return 0;
        while (int(fact_vec.size()) <= i) extend();
        return fact_vec[i];
    }
    T invfact(int i){
        if (i < 0) return 0;
        while (int(fact_inv_vec.size()) <= i) extend();
        return fact_inv_vec[i];
    }
    T C(int a, int b){
        if (a < b || b < 0) return 0;
        return fact(a) * invfact(b) * invfact(a - b);
    }
};
}

// https://ferin-tech.hatenablog.com/entry/2019/08/11/ラグランジュ補間
// x座標が相異なるn+1点(x_i,y_i)を通るn次以下の多項式f(x)を返す
// O(n^2)
#define REP(i, a) for (int i = 0; i < a; i++)
#define FOR(i, a, b) rep(i, a, b)
vector<mint> lagrange_interpolation(vector<mint> x, vector<mint> y) {
    const ll n = x.size() - 1;
    REP(i, n+1) {
        mint t = 1;
        REP(j, n+1) if(i != j) t *= x[i]-x[j];
        y[i] /= t;
    }
    ll cur = 0, nxt = 1;
    vector<vector<mint>> dp(2, vector<mint>(n+2));
    dp[0][0] = -1 * x[0], dp[0][1] = 1;
    FOR(i, 1, n+1) {
        REP(j, n+2) {
            dp[nxt][j] = dp[cur][j] * -1 * x[i];
            if(j >= 1) dp[nxt][j] += dp[cur][j-1];
        }
        swap(nxt, cur);
    }
    vector<mint> xinv(n+1);
    REP(i, n+1) xinv[i] = x[i].inv();
    vector<mint> ret(n+1);  // f(x)
    REP(i, n+1) {
        if(y[i]==0) continue;
        // 0割り対策の場合分け
        if(x[i] == 0) {
            REP(j, n+1) ret[j] += dp[cur][j+1] * y[i];
        } else {
            ret[0] -= dp[cur][0] * xinv[i] * y[i];
            mint pre = -1 * dp[cur][0] * xinv[i];
            FOR(j, 1, n+1) {
                ret[j] -= (dp[cur][j] - pre) * xinv[i] * y[i];
                pre = -1 * (dp[cur][j] - pre) * xinv[i];
            }
        }
    }
    return ret;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int N, P;
    cin >> N >> P;
    mint::set_mod(P);
    int H = N / 2 ;
    int M = N * (N - 1) / 2;
    vector<mint> ans(M + 1);
    po167::Binomial<mint> table(N);
    
    rep(rp, 0, M + 1) {
        vector dp(N + 1, vector(H + 1, vector<mint>(H + 1)));
        dp[1][1][1] = 1;
        vector<mint> p2(N * N + 1, 1);
        rep(i, 0, N * N) p2[i + 1] = p2[i] * (rp + 2);
        vector p3(N, vector<mint>(N));
        rep(i, 0, N){
            p3[i][0] = 1;
            rep(j, 1, N){
                p3[i][j] = p3[i][j - 1] * (p2[i] - 1);
            }
        }
        rep(sum, 1, N) rep(fr, 1, min(H, sum) + 1) rep(a, fr, H + 1) if(dp[sum][fr][a].val()){
            rep(k, 1, min(N - sum, H) + 1) {
                int b = sum - a + k;
                if (b > H) break;
                mint tmp = dp[sum][fr][a] * table.C(N - sum, k);
                tmp *= p3[fr][k];
                tmp *= p2[k * (k - 1) / 2];
                dp[sum + k][k][b] += tmp;
            }
        }
        rep(i, 0, H + 1) ans[rp] += dp[N][i][H];
    }
    
    vector<mint> X(M + 1);
    rep(i, 0, M + 1) X[i] = i + 1;
    auto res = lagrange_interpolation(X, ans);
    rep(i, N - 1, M + 1){
        cout << res[i].val() << (i == M ? "\n" : " ");
    }
}

Submission Info

Submission Time
Task G - Odd Even Graph
User potato167
Language C++ 17 (gcc 12.2)
Score 600
Code Size 4093 Byte
Status AC
Exec Time 71 ms
Memory 3576 KiB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 600 / 600
Status
AC × 3
AC × 15
Set Name Test Cases
Sample 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt
All 00_sample_00.txt, 00_sample_01.txt, 00_sample_02.txt, 01_random_00.txt, 01_random_01.txt, 01_random_02.txt, 01_random_03.txt, 01_random_04.txt, 01_random_05.txt, 01_random_06.txt, 01_random_07.txt, 01_random_08.txt, 01_random_09.txt, 01_random_10.txt, 01_random_11.txt
Case Name Status Exec Time Memory
00_sample_00.txt AC 1 ms 3444 KiB
00_sample_01.txt AC 1 ms 3576 KiB
00_sample_02.txt AC 1 ms 3492 KiB
01_random_00.txt AC 1 ms 3544 KiB
01_random_01.txt AC 1 ms 3364 KiB
01_random_02.txt AC 1 ms 3464 KiB
01_random_03.txt AC 2 ms 3476 KiB
01_random_04.txt AC 4 ms 3496 KiB
01_random_05.txt AC 5 ms 3496 KiB
01_random_06.txt AC 8 ms 3500 KiB
01_random_07.txt AC 12 ms 3516 KiB
01_random_08.txt AC 21 ms 3504 KiB
01_random_09.txt AC 30 ms 3420 KiB
01_random_10.txt AC 46 ms 3428 KiB
01_random_11.txt AC 71 ms 3432 KiB