結果
問題 | No.1145 Sums of Powers |
ユーザー |
|
提出日時 | 2025-01-23 20:42:36 |
言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 18,099 bytes |
コンパイル時間 | 16,446 ms |
コンパイル使用メモリ | 239,020 KB |
実行使用メモリ | 58,288 KB |
最終ジャッジ日時 | 2025-01-23 20:42:59 |
合計ジャッジ時間 | 23,496 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | WA * 5 TLE * 1 |
ソースコード
// include//------------------------------------------#include <string>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <complex>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <cstring>#include <ctime>// namespaceusing namespace std;// temporary#include <atcoder/all>using namespace atcoder;#define RET(x) return cout << x << endl, 0;// for loop#define REP(i, a, b) for ((i) = (ll)(a); (i) < (ll)(b); (i)++)#define REPD(i, a, b) for (ll i = (ll)(a); (i) < (ll)(b); (i)++)#define REPI(v, vs) for (auto &v : vs)// debug#ifdef LOCAL_ENV#define DUMP(x) cerr << #x << " = " << (x) << endl#define DEBUG(x) cerr << #x << " = " << (x) << " (l" << __LINE__ << ")" \<< " " << __FILE__ << endl#else#define DUMP(x)#define DEBUG(x)#endif#define MAX_VALUE 9223372036854775807LL// type aliasusing ll = long long;using ull = unsigned long long;using comp = complex<double>;using llpair = pair<ll, ll>;template <class T>using vector2d = vector<vector<T>>;template <class T>using vector3d = vector<vector<vector<T>>>;using ll1d = vector<ll>;using ll2d = vector2d<ll>;using ll3d = vector3d<ll>;// constantstatic constexpr ll MOD = 998244353LL;constexpr ll MOD_PRIMITIVE_ROOT = 3LL;constexpr ll MOD_INVERSE_PRIMITIVE_ROOT = 332748118LL;static constexpr double PI = 3.14159265358979323846;template <ull N, class T, class... Args, std::enable_if_t<N == 0, int> = 0>auto make_multiple_vector(Args... args){return T(args...);}template <ull N, class T, class... Args, std::enable_if_t<N != 0, int> = 0>auto make_multiple_vector(ull size, Args... args){using value_type = std::decay_t<decltype(make_multiple_vector<N - 1, T>(args...))>;return vector<value_type>(size, make_multiple_vector<N - 1, T>(args...));}using rll = atcoder::modint998244353;inline ull get_power2_more_than_input(ull input){// val is 0.if (input == 0ULL)return 1ULL;// val is power of 2if (!(input & (input - 1)))return input;ull highest_one_bit = input;while ((highest_one_bit & (highest_one_bit - 1LL)) != 0)highest_one_bit = highest_one_bit & (highest_one_bit - 1LL);ull power2 = highest_one_bit << 1LL;return power2;}inline ull get_value_more_than_log_2_input(ull input){auto get_power2 = [](ull input){// val is 0.if (input == 0ULL)return 1ULL;// val is power of 2if (!(input & (input - 1)))return input;ull highest_one_bit = input;while ((highest_one_bit & (highest_one_bit - 1LL)) != 0)highest_one_bit = highest_one_bit & (highest_one_bit - 1LL);ull power2 = highest_one_bit << 1LL;return power2;};auto power2 = get_power2(input);ull value = 0ULL;while (power2 > 1ULL){power2 >>= 1LL;++value;}return value;}// Fast Modulo Transformvector<rll> fmt_impl(const vector<rll> &function, const rll primitive_root){ll degree = function.size();if (degree == 0LL)throw runtime_error("配列の要素数は 1 以上である必要があります。");if ((degree & (degree - 1LL)) != 0LL)throw runtime_error("配列の要素数は 2 のべき乗である必要があります。");auto get_power2 = [&](rll base, ull exponential){rll result = 1;while (exponential >= 1){if (exponential & 1){result = result * base;}base = base * base;exponential >>= 1;}return result;};rll xi = get_power2(rll(primitive_root), (MOD - 1LL) / degree);vector<rll> transformed(degree, 0);vector<rll> stored(degree, 0);for (ll i = 0; i < degree; ++i)transformed[i] = function[i];if (degree == 1LL){return transformed;}ll log_2_deg = 0LL;for (ll i = 1; i < degree; i <<= 1LL)++log_2_deg;vector<rll> mod_xi_2s(log_2_deg);vector<ll> power_2s(log_2_deg);mod_xi_2s[0] = xi, power_2s[0] = 1LL;for (ll i = 1; i < log_2_deg; ++i)mod_xi_2s[i] = mod_xi_2s[i - 1LL] * mod_xi_2s[i - 1LL], power_2s[i] = 1LL << i;for (ll e = 0; e < log_2_deg; ++e){auto mod_xi = mod_xi_2s[log_2_deg - e - 1LL];auto skip = power_2s[log_2_deg - e - 1LL];for (ll i = 0; i < degree; ++i)stored[i] = transformed[i];rll power_of_xi = 1;for (ll i = 0; i < (degree / skip); ++i){for (ll start = 0; start < skip; ++start){auto idx = start + skip * i;auto res_i = i % (degree / skip / 2LL);auto stored_idx = start + skip * res_i * 2LL;transformed[idx] = stored[stored_idx] + stored[stored_idx + skip] * power_of_xi;}power_of_xi = power_of_xi * mod_xi;}}return transformed;}vector<rll> fmt(const vector<rll> &function){vector<rll> transformed = fmt_impl(function, MOD_PRIMITIVE_ROOT);return transformed;}vector<rll> inv_fmt(const vector<rll> &function){vector<rll> transformed = fmt_impl(function, MOD_INVERSE_PRIMITIVE_ROOT);auto inverse_n = rll(1) / rll(function.size());for (unsigned int i = 0; i < function.size(); ++i)transformed[i] = transformed[i] * inverse_n;return transformed;}vector<rll> fmt_convolution(const vector<rll> &a, const vector<rll> &b){unsigned int coef_num = a.size() + b.size() - 1U;unsigned int fmt_size = get_power2_more_than_input(coef_num);vector<rll> rll_a(fmt_size);vector<rll> rll_b(fmt_size);for (unsigned int i = 0; i < a.size(); ++i)rll_a[i] = a[i];for (unsigned int i = 0; i < b.size(); ++i)rll_b[i] = b[i];auto fmt_a = fmt(rll_a);auto fmt_b = fmt(rll_b);vector<rll> fmt_ab(fmt_size);for (unsigned int i = 0; i < fmt_size; ++i)fmt_ab[i] = fmt_a[i] * fmt_b[i];auto rll_ab = inv_fmt(fmt_ab);return rll_ab;}vector<rll> my_convolution(const vector<rll> &a, const vector<rll> &b){return fmt_convolution(a, b);}template <class Number>class Polynomial{private:public:vector<Number> coefs;Polynomial() : coefs(1U) {}Polynomial(Number constant) : coefs(1U, constant) {}Polynomial(vector<Number> coefs) : coefs(coefs) {}static Polynomial zero_polynomial(unsigned int coef_num){vector<Number> coefs(coef_num);return Polynomial(coefs);}Number operator[](unsigned int n) const{return (n < coefs.size() ? coefs[n] : Number(0));}Number &operator[](unsigned int n){if (n >= coefs.size())coefs.resize(n + 1U);return coefs[n];}unsigned int coef_num() const { return coefs.size(); }Number operator()(Number point) const{unsigned int N = coef_num();Number result = 0;Number point_power = 1;for (unsigned int i = 0; i < N; ++i){result = result + coefs[i] * point_power;point_power = point_power * point;result = mod_red(result);point_power = mod_red(point_power);}return result;}void resize(unsigned int n) { coefs.resize(n); }void mod_xn(unsigned int n) { coefs.resize(n); }void zero_trim(){unsigned int N = coef_num();unsigned int max_coef_idx = 1;for (unsigned int i = 0; i < N; ++i)if (coefs[N - i - 1U] != 0){max_coef_idx = N - i;break;}coefs.resize(max_coef_idx);}};template <class Number>Polynomial<Number> operator+(const Polynomial<Number> &lhs, const Polynomial<Number> &rhs){unsigned int coef_num = max(lhs.coef_num(), rhs.coef_num());auto outputs = Polynomial<Number>::zero_polynomial(coef_num);for (unsigned int i = 0; i < coef_num; ++i){outputs[i] = 0;if (i < lhs.coef_num())outputs[i] += lhs[i];if (i < rhs.coef_num())outputs[i] += rhs[i];}return outputs;}template <class Number>Polynomial<Number> operator+(const Polynomial<Number> &lhs, Number rhs){unsigned int coef_num = lhs.coef_num();auto outputs = Polynomial<Number>::zero_polynomial(coef_num);outputs[0] = rhs;for (unsigned int i = 0; i < coef_num; ++i)outputs[i] = outputs[i] + lhs[i];return {outputs};}template <class Number>Polynomial<Number> operator+(Number lhs, const Polynomial<Number> &rhs){unsigned int coef_num = rhs.coef_num();auto outputs = Polynomial<Number>::zero_polynomial(coef_num);outputs[0] = lhs;for (unsigned int i = 0; i < coef_num; ++i)outputs[i] = outputs[i] + rhs[i];return {outputs};}template <class Number>Polynomial<Number> operator-(const Polynomial<Number> &lhs, const Polynomial<Number> &rhs){unsigned int coef_num = max(lhs.coef_num(), rhs.coef_num());auto output = Polynomial<Number>::zero_polynomial(coef_num);for (unsigned int i = 0; i < coef_num; ++i){output[i] = 0;if (i < lhs.coef_num())output[i] = output[i] + lhs[i];if (i < rhs.coef_num())output[i] = output[i] - rhs[i];}return output;}template <class Number>Polynomial<Number> operator-(const Polynomial<Number> &lhs, Number rhs){unsigned int coef_num = lhs.coef_num();auto outputs = Polynomial<Number>::zero_polynomial(coef_num);outputs[0] = -rhs;for (unsigned int i = 0; i < coef_num; ++i)outputs[i] += lhs[i];return {outputs};}template <class Number>Polynomial<Number> operator-(Number lhs, const Polynomial<Number> &rhs){unsigned int coef_num = rhs.coef_num();auto outputs = Polynomial<Number>::zero_polynomial(coef_num);outputs[0] = lhs;for (unsigned int i = 0; i < coef_num; ++i)outputs[i] -= rhs[i];return {outputs};}template <class Number>Polynomial<Number> operator-(const Polynomial<Number> &original){unsigned int coef_num = original.coef_num();auto outputs = Polynomial<Number>::zero_polynomial(coef_num);for (unsigned int i = 0; i < coef_num; ++i){outputs[i] = 0;outputs[i] -= original[i];}return {outputs};}template <class Number>Polynomial<Number> operator*(const Polynomial<Number> &lhs, const Polynomial<Number> &rhs){// Polynomial<Number> output(atcoder::convolution<MOD>(lhs.coefs, rhs.coefs));Polynomial<Number> output(my_convolution(lhs.coefs, rhs.coefs));return output;}template <class Number>Polynomial<Number> derivative_f(const Polynomial<Number> &f){unsigned int coef_num = f.coef_num();auto diff_f = Polynomial<Number>::zero_polynomial(max(1U, coef_num - 1U));for (unsigned int i = 1; i < coef_num; i++)diff_f[i - 1] = f[i] * Number(i);return diff_f;}template <class Number>Polynomial<Number> integral_f(const Polynomial<Number> &f){unsigned int coef_num = f.coef_num();auto integral_f = Polynomial<Number>::zero_polynomial(coef_num);for (unsigned int i = 0; i < coef_num; i++)integral_f[i + 1] = f[i] * Number(i + 1U);return integral_f;}template <class Number>Polynomial<Number> inv(const Polynomial<Number> &f, unsigned int exponent){Polynomial<Number> gn(Number(1) / f[0]), truncated_f(f[0]);for (unsigned int e = 0; e < exponent; e++){auto curr_pow = 1LL << e;auto next_pow = 1LL << (e + 1U);for (unsigned int i = curr_pow; i < next_pow; ++i)if (f[i] != 0)truncated_f[i] = f[i];auto gg = gn * gn;gg.mod_xn(next_pow);auto ggf = gg * truncated_f;for (unsigned int i = 0; i < next_pow; ++i)gn[i] = gn[i] * 2LL - ggf[i];}return gn;}template <class Number>Polynomial<Number> log(const Polynomial<Number> &f, unsigned int exponent){auto pow = 1LL << exponent;auto inv_f = inv(f, exponent);auto diff_f = derivative_f(f);auto integrand = inv_f * diff_f;integrand.mod_xn(pow);auto int_f = integral_f(integrand);return int_f;}template <class Number>Polynomial<Number> operator/(const Polynomial<Number> &lhs, const Polynomial<Number> &rhs){auto reverse_polynomial = [](const Polynomial<Number> &poly){unsigned int LN = poly.coef_num();vector<Number> poly_rev_coefs;poly_rev_coefs.reserve(LN);for (unsigned int i = 0; i < LN; ++i){auto poly_coef = poly[LN - i - 1U];poly_rev_coefs.emplace_back(poly_coef);}return Polynomial<Number>(poly_rev_coefs);};auto trim_and_reverse_polynomial = [](const Polynomial<Number> &poly){unsigned int LN = poly.coef_num();vector<Number> poly_rev_coefs;for (unsigned int i = 0; i < LN; ++i){auto poly_coef = poly[LN - i - 1U];if (poly_rev_coefs.size() == 0){if (poly_coef != 0)poly_rev_coefs.reserve(LN - i);elsecontinue;}poly_rev_coefs.emplace_back(poly_coef);}return Polynomial<Number>(poly_rev_coefs);};auto lhs_rev = trim_and_reverse_polynomial(lhs);auto rhs_rev = trim_and_reverse_polynomial(rhs);auto lhs_rev_coef_num = lhs_rev.coef_num();auto rhs_rev_coef_num = rhs_rev.coef_num();if (lhs_rev_coef_num < rhs_rev_coef_num)return {0};auto diff_coef_num = lhs_rev_coef_num - rhs_rev_coef_num + 1U;ll exponent = 0;ull n = diff_coef_num;while (n != 0){exponent++;n >>= 1LL;}auto rev_q = Polynomial<Number>(lhs_rev) * inv(Polynomial<Number>(rhs_rev), exponent);rev_q.mod_xn(diff_coef_num);auto q = reverse_polynomial(rev_q);return q;}template <class Number>Polynomial<Number> operator%(const Polynomial<Number> &lhs, const Polynomial<Number> &rhs){auto q = lhs / rhs;auto r = lhs - rhs * q;auto r_coef_num = r.coef_num();if (rhs.coef_num() >= 2U)r_coef_num = min(r_coef_num, rhs.coef_num() - 1U);r.mod_xn(r_coef_num);return r;}template <class Number>Polynomial<Number> exp(const Polynomial<Number> &f, unsigned int exponent){Polynomial<Number> gn(1), truncated_f(f[0]);for (unsigned int e = 0; e < exponent; e++){auto curr_pow = 1LL << e;auto next_pow = 1LL << (e + 1U);for (unsigned int i = curr_pow; i < next_pow; ++i)if (f[i] != 0)truncated_f[i] = f[i];auto gf = gn * truncated_f;auto log_g = log(gn, e + 1U);log_g.mod_xn(next_pow);auto g_log_g = gn * log_g;for (unsigned int i = 0; i < next_pow; ++i)gn[i] = Polynomial<Number>::mod_red(gf[i] + gn[i] - g_log_g[i]);}return gn;}template <class Number>pair<Polynomial<Number>, Polynomial<Number>> prod(const vector<Polynomial<Number>> &polys){struct NodeInfo{ll left_idx;ll right_idx;ll size;Polynomial<Number> numerator;Polynomial<Number> denominator;NodeInfo(ll left_idx,ll right_idx,ll size,Polynomial<Number> numerator,Polynomial<Number> denominator) : left_idx(left_idx), right_idx(right_idx), size(size), numerator(numerator), denominator(denominator) {}};vector<NodeInfo> node_infos;queue<ll> node_queue;ll node_idx = 0;for (unsigned int i = 0; i < polys.size(); ++i){node_infos.emplace_back(-1LL, -1LL, 1LL, Polynomial<Number>(1), polys[i]);node_queue.emplace(node_idx);++node_idx;}while (true){if (node_queue.empty())break;auto i1 = node_queue.front();node_queue.pop();if (node_queue.empty())break;auto i2 = node_queue.front();node_queue.pop();auto size1 = node_infos[i1].size;auto size2 = node_infos[i2].size;auto numerator1 = node_infos[i1].numerator;auto numerator2 = node_infos[i2].numerator;auto denominator1 = node_infos[i1].denominator;auto denominator2 = node_infos[i2].denominator;auto new_numerator = numerator1 * denominator2 + numerator2 * denominator1;auto new_denominator = denominator1 * denominator2;new_numerator.zero_trim();new_denominator.zero_trim();node_infos.emplace_back(i1, i2, size1 + size2, new_numerator, new_denominator);node_queue.emplace(node_idx);++node_idx;}vector<Polynomial<Number>> residues(node_idx);--node_idx;return {node_infos[node_idx].numerator, node_infos[node_idx].denominator};}ll N, M;int solve(){cin >> N >> M;vector<Polynomial<rll>> polys(N);REPD(i, 0, N){ll a;cin >> a;polys[i] = vector<rll>{rll(1), rll(-a)};}auto [numerator, denominator] = prod(polys);auto formal_denominator = inv(denominator, get_value_more_than_log_2_input(M + 2));formal_denominator.zero_trim();auto results = numerator * formal_denominator;REPD(i, 1, M + 1){cout << results[i].val() << endl;}return 0;}// main functionint main(){cin.tie(0);ios::sync_with_stdio(false);solve();// ll t;// cin >> t;// REPD(i, 0, t)// {// solve();// }return 0;}