結果
問題 | No.1145 Sums of Powers |
ユーザー | Aoxiang Cui |
提出日時 | 2021-08-08 09:56:42 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 514 ms / 2,000 ms |
コード長 | 8,396 bytes |
コンパイル時間 | 1,673 ms |
コンパイル使用メモリ | 128,520 KB |
実行使用メモリ | 10,708 KB |
最終ジャッジ日時 | 2024-09-19 05:43:20 |
合計ジャッジ時間 | 3,897 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 4 ms
5,376 KB |
testcase_03 | AC | 514 ms
10,580 KB |
testcase_04 | AC | 507 ms
10,580 KB |
testcase_05 | AC | 511 ms
10,708 KB |
ソースコード
// #define LOCAL #define _USE_MATH_DEFINES #include <array> #include <cassert> #include <cstdio> #include <cstring> #include <iostream> #include <iomanip> #include <string> #include <sstream> #include <vector> #include <queue> #include <stack> #include <list> #include <set> #include <map> #include <unordered_set> #include <unordered_map> #include <algorithm> #include <complex> #include <cmath> #include <numeric> #include <bitset> #include <functional> #include <random> #include <ctime> using namespace std; template <typename A, typename B> ostream& operator <<(ostream& out, const pair<A, B>& a) { out << "(" << a.first << "," << a.second << ")"; return out; } template <typename T, size_t N> ostream& operator <<(ostream& out, const array<T, N>& a) { out << "["; bool first = true; for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "]"; return out; } template <typename T> ostream& operator <<(ostream& out, const vector<T>& a) { out << "["; bool first = true; for (auto v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "]"; return out; } template <typename T, class Cmp> ostream& operator <<(ostream& out, const set<T, Cmp>& a) { out << "{"; bool first = true; for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "}"; return out; } template <typename U, typename T, class Cmp> ostream& operator <<(ostream& out, const map<U, T, Cmp>& a) { out << "{"; bool first = true; for (auto& p : a) { out << (first ? "" : ", "); out << p.first << ":" << p.second; first = 0;} out << "}"; return out; } #ifdef LOCAL #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__) #else #define trace(...) 42 #endif template <typename Arg1> void __f(const char* name, Arg1&& arg1){ cerr << name << ": " << arg1 << endl; } template <typename Arg1, typename... Args> void __f(const char* names, Arg1&& arg1, Args&&... args){ const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << ": " << arg1 << " |"; __f(comma + 1, args...); } template <class T> auto vect(const T& v, int n) { return vector<T>(n, v); } template <class T, class... D> auto vect(const T& v, int n, D... m) { return vector<decltype(vect(v, m...))>(n, vect(v, m...)); } typedef long long int64; typedef pair<int, int> ii; #define SZ(x) (int)((x).size()) template <typename T> static constexpr T inf = numeric_limits<T>::max() / 2; // const int MOD = 1e9 + 7; const int MOD = 998244353; mt19937 mrand(random_device{}()); int rnd(int x) { return mrand() % x; } // mt19937_64 mrand(random_device{}()); // int64 rnd(int64 x) { return mrand() % x; } template <class T> void out(const vector<T>& a) { for (int i = 0; i < SZ(a); ++i) cout << a[i] << " \n"[i + 1 == SZ(a)]; } template <class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; } template <class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } template <class T> void dedup(vector<T>& v) { sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); } void add(int& x, int y) { x += y; if (x >= MOD) x -= MOD; } struct fast_ios { fast_ios() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(10); }; } fast_ios_; // const int MOD = 998244353; // prime, 2^23*7*17+1 typedef int atom; const int G = 3; int64 power_mod(int64 a, int64 n, int p = MOD) { int64 ret = 1; for (; n; n >>= 1) { if (n & 1) ret = ret * a % p; a = a * a % p; } return ret; } int64 inv_mod(int64 a) { return power_mod(a, MOD - 2); } void bit_reverse(vector<atom>& a) { int n = a.size(); for (int i = 1, j = n / 2; i < n - 1; ++i) { if (i < j) swap(a[i], a[j]); int k = n / 2; while (j >= k) j -= k, k /= 2; if (j < k) j += k; } } void fft(vector<atom>& a, int flag) { int n = a.size(); bit_reverse(a); vector<atom> wn(n); wn[0] = 1; wn[1] = power_mod(G, flag == 1 ? (MOD - 1) / n : MOD - 1 - (MOD - 1) / n); for (int i = 2; i < n; ++i) wn[i] = (int64)wn[i - 1] * wn[1] % MOD; for (int k = 2; k <= n; k <<= 1) { for (int i = 0; i < n; i += k) { int wi = 0, step = n / k; for (int j = i; j < i + k / 2; ++j) { atom u = a[j]; atom v = (int64)wn[wi] * a[j + k / 2] % MOD; a[j] = (u + v) % MOD; a[j + k / 2] = (u + MOD - v) % MOD; wi += step; } } } if (flag < 0) { int64 inv_n = inv_mod(n); for (int i = 0; i < n; ++i) a[i] = a[i] * inv_n % MOD; } } namespace polynomial { vector<int> mul(const vector<int>& f, const vector<int>& g, int cap = inf<int>) { int n = f.size(), m = g.size(); int len = 1; while (len < n + m - 1) len <<= 1; vector<atom> x(len), y(len); copy(f.begin(), f.end(), x.begin()); copy(g.begin(), g.end(), y.begin()); fft(x, 1); fft(y, 1); for (int i = 0; i < len; ++i) x[i] = (int64)x[i] * y[i] % MOD; fft(x, -1); cap = min(cap, n + m - 1); x.resize(cap); return x; } vector<int> differential(const vector<int>& f) { int n = f.size(); vector<int> ret(n); for (int i = 0; i < n - 1; ++i) ret[i] = (int64)f[i + 1] * (i + 1) % MOD; return ret; } void integral(vector<int>& f) { int n = f.size(); for (int i = n - 1; i > 0; --i) f[i] = inv_mod(i) * f[i - 1] % MOD; f[0] = 0; } // g:=g*(2-f*g), n is power of 2 vector<int> inverse(const vector<int>& f) { int n = f.size(); if (n == 1) return {(int)inv_mod(f[0])}; vector<int> f1(f.begin(), f.begin() + (n >> 1)); auto g = inverse(f1); g.resize(n); auto h = mul(f, g, n); h[0] = (2 + MOD - h[0]) % MOD; for (int i = 1; i < h.size(); ++i) h[i] = (MOD - h[i]) % MOD; return mul(h, g, n); } pair<vector<int>, vector<int>> div(const vector<int>& f, const vector<int>& g) { int n = f.size(), m = g.size(); int k = n - m + 1; if (n < m) return make_pair(vector<int>{0}, f); int len = 1; while (len < m) len <<= 1; vector<int> fr(n), gr(len); copy(f.rbegin(), f.rend(), fr.begin()); copy(g.rbegin(), g.rend(), gr.begin()); auto h = inverse(gr); h = mul(fr, h); vector<int> d(k); for (int i = 0; i < k; ++i) d[i] = h[k - 1 - i]; h = mul(g, d); vector<int> r(m); for (int i = 0; i < m; ++i) r[i] = (f[i] + MOD - h[i]) % MOD; int deg_r = m - 1; while (deg_r && r[deg_r] == 0) --deg_r; r.resize(deg_r + 1); return make_pair(d, r); } int64 W; ii operator *(const ii& u, const ii& v) { return {((int64)u.first * v.first + (int64)u.second * v.second % MOD * W) % MOD, ((int64)u.first * v.second + (int64)u.second * v.first) % MOD}; } ii power_mod(ii a, int64 n) { ii ret = {1, 0}; for (; n; n >>= 1) { if (n & 1) ret = ret * a; a = a * a; } return ret; } int cipolla(int x) { int y; while (true) { y = rnd(MOD); W = ((int64)y * y % MOD + MOD - x) % MOD; if (::power_mod(W, (MOD - 1) / 2) > 1) break; } ii ret(y, 1); ret = power_mod(ret, (MOD + 1) / 2); return min(ret.first, MOD - ret.first); } // g:=(g+f/g)/2, n is power of 2 vector<int> sqrt(const vector<int>& f) { int n = f.size(); if (n == 1) return {cipolla(f[0])}; vector<int> f1(f.begin(), f.begin() + (n >> 1)); auto g = sqrt(f1); g.resize(n); auto h = inverse(g); h = mul(f, h, n); int64 inv2 = inv_mod(2); for (int i = 0; i < n; ++i) g[i] = (g[i] + h[i]) * inv2 % MOD; return g; } // g=integral(f'/f), n is power of 2 vector<int> log(const vector<int>& f) { auto g = differential(f); auto h = inverse(f); auto ret = mul(g, h); ret.resize(f.size()); integral(ret); return ret; } // g:=g*(1-log(g)+f), n is power of 2 vector<int> exp(const vector<int>& f) { int n = f.size(); if (n == 1) return vector<int>{1}; vector<int> f1(f.begin(), f.begin() + (n >> 1)); auto g = exp(f1); g.resize(n); auto h = log(g); for (int i = 0; i < n; ++i) h[i] = ((i == 0) + f[i] + MOD - h[i]) % MOD; return mul(g, h, n); } } using namespace polynomial; const int N = 1e5 + 10; int a[N]; vector<int> solve(int L, int R) { if (L + 1 == R) return {1, MOD - a[L]}; int mid = (L + R) / 2; return mul(solve(L, mid), solve(mid, R)); } int main() { int n, m; cin >> n >> m; for (int i = 0; i < n; ++i) cin >> a[i]; auto f = solve(0, n); trace(f); int len = 1; while (len <= m) len *= 2; f.resize(len); f = log(f); vector<int> ret(m); for (int k = 1; k <= m; ++k) { ret[k - 1] = (MOD - 1LL * f[k] * k % MOD) % MOD; } out(ret); return 0; }