結果
| 問題 | No.2580 Hyperinflation |
| コンテスト | |
| ユーザー |
tute7627
|
| 提出日時 | 2023-12-08 21:46:58 |
| 言語 | C++17(gcc12) (gcc 12.4.0 + boost 1.89.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,382 bytes |
| 記録 | |
| コンパイル時間 | 6,142 ms |
| コンパイル使用メモリ | 407,084 KB |
| 実行使用メモリ | 6,528 KB |
| 最終ジャッジ日時 | 2026-07-03 05:33:34 |
| 合計ジャッジ時間 | 7,809 ms |
|
ジャッジサーバーID (参考情報) |
judge2_0 / judge1_0 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 13 WA * 18 |
ソースコード
// https://atcoder.jp/contests/arc118/submissions/24453032
#include <bits/stdc++.h>
#include <atcoder/convolution>
using Fp = atcoder::modint998244353;
std::ostream& operator<<(std::ostream& os, Fp a) { return os << a.val(); }
using Fps = std::vector<Fp>;
int sz(const Fps& a) { return a.size(); }
Fps operator-(Fps a) {
for (auto&& e : a) e = -e;
return a;
}
Fps& operator+=(Fps& a, const Fps& b) {
if (sz(a) < sz(b)) a.reserve(sz(b)), a.resize(sz(b));
for (int i = 0; i < sz(b); ++i) a[i] += b[i];
return a;
}
Fps operator+(Fps a, const Fps& b) { return std::move(a += b); }
Fps& operator-=(Fps& a, const Fps& b) {
if (sz(a) < sz(b)) a.reserve(sz(b)), a.resize(sz(b));
for (int i = 0; i < sz(b); ++i) a[i] -= b[i];
return a;
}
Fps operator-(Fps a, const Fps& b) { return std::move(a -= b); }
Fps& operator*=(Fps& a, Fp b) {
for (auto&& e : a) e *= b;
return a;
}
Fps operator*(Fps a, Fp b) { return std::move(a *= b); }
Fps operator*(Fp a, Fps b) { return std::move(b *= a); }
Fps& operator/=(Fps& a, Fp b) {
b = b.inv();
for (auto&& e : a) e *= b;
return a;
}
Fps operator/(Fps a, Fp b) { return std::move(a /= b); }
Fps fft(const Fps& a, int n) {
Fps res(n);
std::copy(a.begin(), a.begin() + std::min(n, sz(a)), res.begin());
atcoder::internal::butterfly(res);
return res;
}
Fps circ(Fps&& a, const Fps& b) {
if (sz(a) < sz(b)) a.reserve(sz(b)), a.resize(sz(b));
for (int i = 0; i < sz(b); ++i) a[i] *= b[i];
return a;
}
Fps circ(Fps&& a) {
for (auto&& e : a) e *= e;
return a;
}
Fps ifft(Fps&& a, int size) {
int n = sz(a);
atcoder::internal::butterfly_inv(a);
a.resize(size);
a *= (1 - Fp::mod()) / n;
return a;
}
Fps operator*(const Fps& a, const Fps& b) {
if (a.empty() || b.empty()) return {};
if (std::min(sz(a), sz(b)) <= 60) {
Fps res(std::max(sz(a), sz(b)));
for (int i = 0; i < sz(a); ++i)
for (int j = 0; j < sz(b); ++j) {
if (i + j == sz(res)) break;
res[i + j] += a[i] * b[j];
}
return res;
}
int n = 1 << atcoder::internal::bit_ceil(sz(a) + sz(b) - 1);
auto buf = fft(a, n);
if (&a == &b)
buf = circ(std::move(buf));
else
buf = circ(std::move(buf), fft(b, n));
return ifft(std::move(buf), std::max(sz(a), sz(b)));
}
Fps& operator*=(Fps& a, const Fps& b) { return a = a * b; }
Fps inv(const Fps& a) {
Fps res{a[0].inv()};
for (int n = 1; n < sz(a); n *= 2) {
auto f_res = fft(res, 2 * n);
Fps buf = ifft(circ(fft(a, 2 * n), f_res), 2 * n);
std::fill(buf.begin(), buf.begin() + n, 0);
buf = ifft(circ(fft(buf, 2 * n), f_res), std::min(2 * n, sz(a)));
for (int i = n; i < sz(buf); ++i) res.push_back(-buf[i]);
}
return res;
}
using Poly = std::vector<Fp>;
Fp eval(const Poly& a, Fp x) {
Fp res;
for (int i = sz(a); i--;) (res *= x) += a[i];
return res;
}
std::vector<Fp> fact, ifact;
void reserve(int n) {
fact.resize(n + 1), ifact.resize(n + 1);
fact[0] = 1;
for (int i = 1; i <= n; ++i) fact[i] = i * fact[i - 1];
ifact[n] = fact[n].pow(Fp::mod() - 2);
for (int i = n; i; --i) ifact[i - 1] = ifact[i] * i;
}
using namespace std;
#include<boost/multiprecision/cpp_int.hpp>
int main() {
using namespace std;
cin.tie(nullptr)->sync_with_stdio(false);
using bigint=boost::multiprecision::cpp_int;
int n;
bigint m;
cin >> n;n--;
vector<int> a(n);
bigint mult = 1;
for (auto&& e : a){
cin >> e;
mult *= bigint(e);
}
reverse(a.begin(),a.end());
cin >> m;
m += mult;
reserve(n + 1);
auto calc=[&](bigint m){
Fps bernoulli(n + 1);
for (int i = 0; i <= n; ++i) bernoulli[i] = ifact[i + 1];
bernoulli = inv(bernoulli);
auto faulhaber = [&](Poly f) -> Poly {
for (int i = 0; i < sz(f); ++i) f[i] *= fact[i];
reverse(begin(f), end(f));
f *= Fps(begin(bernoulli), begin(bernoulli) + sz(f));
f.push_back(0);
reverse(begin(f), end(f));
for (int i = 0; i < sz(f); ++i) f[i] *= ifact[i];
return f;
};
Poly f{1};
for (int i = n; i--;) {
Poly g = faulhaber(f);
f = -g;
Fp coeff = 1;
for (int j = 1; j < sz(f); ++j) f[j] *= coeff *= a[i];
f[0] = eval(g, static_cast<int>((m + 1)%bigint(998244353)));
m /= bigint(a[i]);
}
f = faulhaber(f);
return eval(f,static_cast<int> ((m + 1)%bigint(998244353))) - eval(f, 1);
};
cout << calc(m) - calc(m-1) << '\n';
}
tute7627