結果

問題 No.3451 Same Numbers
コンテスト
ユーザー 👑 potato167
提出日時 2026-01-27 16:04:12
言語 C++17
(gcc 15.2.0 + boost 1.89.0)
結果
WA  
(最新)
AC  
(最初)
実行時間 -
コード長 2,679 bytes
記録
記録タグの例:
初AC ショートコード 純ショートコード 純主流ショートコード 最速実行時間
コンパイル時間 2,528 ms
コンパイル使用メモリ 227,680 KB
実行使用メモリ 7,976 KB
最終ジャッジ日時 2026-02-20 20:52:34
合計ジャッジ時間 8,492 ms
ジャッジサーバーID
(参考情報)
judge2 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample WA * 3
other AC * 5 WA * 32
権限があれば一括ダウンロードができます

ソースコード

diff #
raw source code

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

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);
    }
    T invC(int a, int b){
        if (a < b || b < 0) return 0;
        return fact(b) * fact(a - b) *invfact(a);
    }
    T inv(int a){
        if (a < 0) return inv(-a) * T(-1);
        if (a == 0) return 1;
        return fact(a - 1) * invfact(a);
    }
};
}

// O(V^1.5)
vector<mint> solve4(int N, int M){
    po167::Binomial<mint> table;
    vector<mint> res(N, 1);
    int B = 0;
    while (B * B < M && B < N - 1) B++;
    res[N - 1] = (M - 1) / N + 1;
    vector<mint> dp(M + B);
    rep(k, 0, B){
        mint inv = table.inv(N - k);
        dp[k + 1] = 1;
        rep(i, 0, M){
            dp[i] *= inv;
            res[k] += dp[i];
            dp[i + k + 1] += dp[i];
            dp[i + 1] += dp[i] * (N - k - 1);
            dp[i] = 0;
        }
    }
    rep(k, B, N - 1){
        mint inv = table.inv(N - k - 1);
        // N - 1 - k * a 回中 a 回未満
        int a = 1;
        while (true){
            int A = M - 1 - k * a;
            int B = a;
            if (A < B) break;
            res[k] += 1;
            mint tmp = table.inv(N - k).pow(A) * (mint(N - k - 1)).pow(A);
            rep(j, 0, a){
                res[k] -= table.C(A, j) * tmp;
                tmp *= inv;
            }
            a++;
        }
    }
    return res;
}

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

	int N, M;
	cin >> N >> M;
	
	auto ans = solve4(N, M);
	for (auto x : ans) cout << x.val() << "\n";
}
0