結果

問題 No.1145 Sums of Powers
コンテスト
ユーザー 👑 potato167
提出日時 2025-10-29 11:30:33
言語 C++17
(gcc 13.3.0 + boost 1.87.0)
結果
AC  
実行時間 361 ms / 2,000 ms
コード長 3,499 bytes
コンパイル時間 2,357 ms
コンパイル使用メモリ 124,024 KB
実行使用メモリ 35,720 KB
最終ジャッジ日時 2025-10-29 11:30:37
合計ジャッジ時間 4,474 ms
ジャッジサーバーID
(参考情報)
judge3 / judge4
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 6
権限があれば一括ダウンロードができます

ソースコード

diff #

#line 1 "b.cpp"
#include <atcoder/convolution>
#line 2 "/Users/Shared/po167_library/fps/FPS_add.hpp"
#include <vector>

namespace po167{
template <class T>
// a(x) += b(x) * c * x^d
void FPS_add(std::vector<T> &a, std::vector<T> b, T c = 1, int d = 0){
    for (int i = 0; i < (int)(b.size()); i++){
        while ((int)a.size() <= i + d) a.push_back((T)0);
        a[i + d] += b[i] * c;
    }
}
}
#line 3 "b.cpp"
namespace po167{
/*
 * return {res, prod L, prod R}
 *
 * res :
 * i = 0, 1, ... , N - 1
 * sum L[0] * ... * L[i - 1] * f[i] * R[i + 1] * ... * R[N - 1]
 */
template<class T>
std::tuple<std::vector<T>, std::vector<T>, std::vector<T>> divide_and_conquer_product(std::vector<std::vector<T>> f, std::vector<std::vector<T>> L, std::vector<std::vector<T>> R = {}){
    int N = f.size();
    assert(N == (int)L.size());
    if (N == 0){
        return {{}, {}, {}};
    }
    auto calc = [&](auto self, int l, int r) -> void {
        if (l + 1 == r) return;
        int m = (l + r) / 2;
        self(self, l, m);
        self(self, m, r);
        if (!R.empty()){
            f[l] = atcoder::convolution(f[l], R[m]);
        }
        else{
            f[l] = atcoder::convolution(f[l], L[m]);
        }
        po167::FPS_add(f[l], atcoder::convolution(f[m], L[l]));
        L[l] = atcoder::convolution(L[l], L[m]);
        if (!R.empty()) R[l] = atcoder::convolution(R[l], R[m]);
    };
    calc(calc, 0, N);
    return {f[0], L[0], (R.empty() ? L[0] : R[0])};
}
}

#line 4 "/Users/Shared/po167_library/fps/FPS_inv.hpp"

namespace po167{
// return 1 / f
template <class T>
std::vector<T> FPS_inv(std::vector<T> f, int len = -1){
    if (len == -1) len = f.size();
    assert(f[0] != 0);
    std::vector<T> g = {1 / f[0]};
    int s = 1;
    while(s < len){
        // g = 2g_s - f(g_s)^2 (mod x ^ (2 * s))
        // g = g - (fg - 1)g
        // (fg - 1) = 0 (mod x ^ (s))
        std::vector<T> n_g(s * 2, 0);
        std::vector<T> f_s(s * 2, 0);
        g.resize(s * 2);
        for (int i = 0; i < s * 2; i++){
            if (int(f.size()) > i) f_s[i] = f[i];
            n_g[i] = g[i];
        }
        atcoder::internal::butterfly(g);
        atcoder::internal::butterfly(f_s);
        for (int i = 0; i < s * 2; i++){
            f_s[i] *= g[i];
        }
        atcoder::internal::butterfly_inv(f_s);
        T iz = 1 / (T)(s * 2);
        for (int i = s; i < s * 2; i++){
            f_s[i] *= iz;
        }
        for (int i = 0; i < s; i++){
            f_s[i] = 0;
        }
        atcoder::internal::butterfly(f_s);
        for (int i = 0; i < s * 2; i++){
            f_s[i] *= g[i];
        }
        atcoder::internal::butterfly_inv(f_s);
        for (int i = s; i < s * 2; i++){
            n_g[i] -= f_s[i] * iz;
        }
        std::swap(n_g, g);
        s *= 2;
    }
    g.resize(len);
    return g;
}
}
#line 39 "b.cpp"

#include <iostream>
using mint = atcoder::modint998244353;
using namespace std;
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    int N, M;
    cin >> N >> M;
    vector<int> A(N);
    for (auto &a : A) cin >> a;
    std::vector<std::vector<mint>> f(N);
    std::vector<std::vector<mint>> L(N);
    for (int i = 0; i < N; i++){
        f[i] = {1};
        L[i] = {1, -A[i]};
    }
    auto [tmp, l, r] = po167::divide_and_conquer_product(f, L);
    tmp = atcoder::convolution(tmp, po167::FPS_inv(l, M + 1));
    for (int i = 1; i <= M; i++){
        cout << (tmp[i]).val() << (i == M ? "\n" : " ");
    }
}
0