結果
問題 | No.1068 #いろいろな色 / Red and Blue and more various colors (Hard) |
ユーザー | SymmetricHorizon |
提出日時 | 2022-03-15 23:43:45 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 4,681 bytes |
コンパイル時間 | 1,649 ms |
コンパイル使用メモリ | 173,228 KB |
実行使用メモリ | 15,156 KB |
最終ジャッジ日時 | 2024-09-22 16:10:47 |
合計ジャッジ時間 | 7,652 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | WA | - |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
testcase_20 | WA | - |
testcase_21 | WA | - |
testcase_22 | WA | - |
testcase_23 | WA | - |
testcase_24 | WA | - |
testcase_25 | WA | - |
testcase_26 | WA | - |
testcase_27 | WA | - |
testcase_28 | WA | - |
testcase_29 | WA | - |
testcase_30 | WA | - |
testcase_31 | AC | 2 ms
5,376 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; #define rep(i, n) for (decltype(n) i = 0; i < (n); ++i) #define rep3(i, s, n) for (decltype(n) i = (s); i < (n); ++i) #define repR(i, n) for (decltype(n) i = (n)-1; i >= 0; --i) #define rep3R(i, s, n) for (decltype(n) i = (n)-1; i >= (s); --i) #define repit(it, c) for (auto it = (c).begin(); it != (c).end(); ++it) #define all(x) ::std::begin(x), ::std::end(x) using ll = long long; template <typename T, typename U> inline bool chmax(T ¤t, const U &test) { if (current < test) { current = test; return true; } return false; } template <typename T, typename U> inline bool chmin(T ¤t, const U &test) { if (current > test) { current = test; return true; } return false; } using ll = long long; ll INF = 2 * 1e9; template <typename T> T pow_mod(T n, T p, T mod) { T ret = 1; while (p > 0) { if (p & 1) { ret = ret * n % mod; } n = n * n % mod; p >>= 1; } return ret; } template <typename T> T ext_gcd(T a, T b, T &x, T &y) { if (b == 0) { x = 1, y = 0; return a; } T d = ext_gcd(b, a % b, y, x); y -= a / b * x; return d; } template <typename T> T inv_mod(T n, T mod) { T x(0), y(0); ext_gcd(n, mod, x, y); return (x % mod + mod) % mod; } template <ll mod, ll primitive_root> // Fast Modulo Transform class FMT { public: ll get_mod() const { return mod; } ll get_primitive_root() const { return primitive_root; } FMT() {} vector<ll> fmt(vector<ll> a, bool inverse = false) { ll n = a.size(); assert((n ^ (n & -n)) == 0); // power of 2 int h = 0; while ((1 << h) < n) { h++; } assert((1 << h) == n); // n == 2^h // bit reversal for (int i = 0; i < n; i++) { int i_rev = 0; for (int bit = 0; bit < h; bit++) { i_rev |= ((i >> bit) & 1) << (h - 1 - bit); } if (i < i_rev) swap(a[i], a[i_rev]); } // 1 の n = 2^e 乗根 ll w = pow_mod(primitive_root, (mod - 1) / n, mod); assert(pow_mod(w, n, mod) == 1); if (inverse) { w = inv_mod(w, mod); } // butterfly operation for (int b = 1; b < n; b *= 2) { // log_2(b) + 1 段 // ブロックサイズ = 2 * b ll base = pow_mod(w, n / (2 * b), mod); ll z = 1; for (int j = 0; j < b; j++) { //ブロック内 j 個目 for (int k = 0; k < n; k += 2 * b) { // k を先頭とするブロック ll s = a[j + k]; ll t = a[j + k + b] * z % mod; a[j + k] = (s + t) % mod; a[j + k + b] = (s - t + mod) % mod; } z = z * base % mod; } } if (inverse) { for (int i = 0; i < n; i++) { a[i] = a[i] * inv_mod(n, mod) % mod; } } return a; } vector<ll> ifmt(vector<ll> a) { return fmt(a, true); } vector<ll> convolve(vector<ll> a, vector<ll> b) { ll sz = a.size() + b.size() - 1; ll n = 1; while (n < sz) { n <<= 1; } a.resize(n); b.resize(n); vector<ll> A = fmt(a); vector<ll> B = fmt(b); for (int i = 0; i < n; i++) { A[i] = A[i] * B[i] % mod; } A = ifmt(A); a.resize(sz); for (int i = 0; i < sz; i++) { a[i] = A[i]; } return a; } }; FMT<998244353, 3> fmt; const ll mod = 998244353; // 分割統治 FFT ってこうで合ってますか? // a: 色 A の配列, 半開区間 [l, r), n: Fourier 空間での配列の長さ vector<ll> rec_convolve(vector<ll> &a, int l, int r, int n) { if (r - l == 1) { vector<ll> ret(n, 0); ret[0] = (a[l] - 1 + mod) % mod; // 色1 以外の場合の数 ret[1] = 1; // 色1 の場合の数 return fmt.fmt(ret); // fast modulo transform } int mid = (l + r) / 2; int sz = r - l + 1; ll nn = 1; while (nn < sz) { nn <<= 1; } vector<ll> ret(n, 0); vector<ll> v1 = rec_convolve(a, l, mid, nn); vector<ll> v2 = rec_convolve(a, mid, r, nn); rep(i, nn) { ret[i] = v1[i] * v2[i] % mod; } return ret; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); constexpr char endl = '\n'; /////////////////////////// // input ll n, q; cin >> n >> q; vector<ll> a(n), b(q); for (auto &e : a) { cin >> e; e %= mod; } for (auto &e : b) { cin >> e; } // solve // 形式的冪級数で答えを書くと // [x^{B_q}] \prod_{i=1}^N ((A_i - 1) + 1 * x) FMT<998244353, 3> fmt; ll m = 1; while (m < n + 1) { m <<= 1; } vector<ll> v = rec_convolve(a, 0, n, m); v = fmt.ifmt(v); // 最後にまとめて inverse fast modulo transform // output rep(i, q) { cout << v[b[i]] << endl; } }