Luzhiled's Library

This documentation is automatically generated by competitive-verifier/competitive-verifier

View the Project on GitHub ei1333/library

:heavy_check_mark: test/verify/yosupo-convolution-mod.test.cpp

Depends on

Code

// clang-format off
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/convolution_mod
// clang-format on

#include <iostream>
#include <vector>

#include "../../math/fft/number-theoretic-transform.hpp"

using namespace std;

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(N), B(M);
  for (auto& a : A) cin >> a;
  for (auto& b : B) cin >> b;
  NumberTheoreticTransform<998244353> ntt;
  for (auto& c : ntt.multiply(A, B)) cout << c << " ";
  cout << endl;
}
#line 1 "test/verify/yosupo-convolution-mod.test.cpp"
// clang-format off
// competitive-verifier: PROBLEM https://judge.yosupo.jp/problem/convolution_mod
// clang-format on

#include <iostream>
#include <vector>

#line 2 "math/fft/number-theoretic-transform.hpp"

#include <algorithm>
#include <cassert>
#line 6 "math/fft/number-theoretic-transform.hpp"

template <int mod>
struct NumberTheoreticTransform {
  std::vector<int> rev, rts;
  int base, max_base, root;

  NumberTheoreticTransform() : base(1), rev{0, 1}, rts{0, 1} {
    assert(mod >= 3 && mod % 2 == 1);
    auto tmp = mod - 1;
    max_base = 0;
    while (tmp % 2 == 0) tmp >>= 1, max_base++;
    root = 2;
    while (mod_pow(root, (mod - 1) >> 1) == 1) ++root;
    assert(mod_pow(root, mod - 1) == 1);
    root = mod_pow(root, (mod - 1) >> max_base);
  }

  inline int mod_pow(int x, int n) {
    int ret = 1;
    while (n > 0) {
      if (n & 1) ret = mul(ret, x);
      x = mul(x, x);
      n >>= 1;
    }
    return ret;
  }

  inline int inverse(int x) { return mod_pow(x, mod - 2); }

  inline unsigned add(unsigned x, unsigned y) {
    x += y;
    if (x >= mod) x -= mod;
    return x;
  }

  inline unsigned mul(unsigned a, unsigned b) {
    return 1ull * a * b % (unsigned long long)mod;
  }

  void ensure_base(int nbase) {
    if (nbase <= base) return;
    rev.resize(1 << nbase);
    rts.resize(1 << nbase);
    for (int i = 0; i < (1 << nbase); i++) {
      rev[i] = (rev[i >> 1] >> 1) + ((i & 1) << (nbase - 1));
    }
    assert(nbase <= max_base);
    while (base < nbase) {
      int z = mod_pow(root, 1 << (max_base - 1 - base));
      for (int i = 1 << (base - 1); i < (1 << base); i++) {
        rts[i << 1] = rts[i];
        rts[(i << 1) + 1] = mul(rts[i], z);
      }
      ++base;
    }
  }

  void ntt(std::vector<int>& a) {
    const int n = (int)a.size();
    assert((n & (n - 1)) == 0);
    int zeros = __builtin_ctz(n);
    ensure_base(zeros);
    int shift = base - zeros;
    for (int i = 0; i < n; i++) {
      if (i < (rev[i] >> shift)) {
        std::swap(a[i], a[rev[i] >> shift]);
      }
    }
    for (int k = 1; k < n; k <<= 1) {
      for (int i = 0; i < n; i += 2 * k) {
        for (int j = 0; j < k; j++) {
          int z = mul(a[i + j + k], rts[j + k]);
          a[i + j + k] = add(a[i + j], mod - z);
          a[i + j] = add(a[i + j], z);
        }
      }
    }
  }

  std::vector<int> multiply(std::vector<int> a, std::vector<int> b) {
    int need = a.size() + b.size() - 1;
    int nbase = 1;
    while ((1 << nbase) < need) nbase++;
    ensure_base(nbase);
    int sz = 1 << nbase;
    a.resize(sz, 0);
    b.resize(sz, 0);
    ntt(a);
    ntt(b);
    int inv_sz = inverse(sz);
    for (int i = 0; i < sz; i++) {
      a[i] = mul(a[i], mul(b[i], inv_sz));
    }
    std::reverse(a.begin() + 1, a.end());
    ntt(a);
    a.resize(need);
    return a;
  }
};
#line 9 "test/verify/yosupo-convolution-mod.test.cpp"

using namespace std;

int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(N), B(M);
  for (auto& a : A) cin >> a;
  for (auto& b : B) cin >> b;
  NumberTheoreticTransform<998244353> ntt;
  for (auto& c : ntt.multiply(A, B)) cout << c << " ";
  cout << endl;
}

Test cases

Env Name Status Elapsed Memory
g++ all_same_00 :heavy_check_mark: AC 174 ms 26 MB
g++ all_same_01 :heavy_check_mark: AC 290 ms 26 MB
g++ all_same_02 :heavy_check_mark: AC 275 ms 26 MB
g++ all_same_03 :heavy_check_mark: AC 273 ms 26 MB
g++ example_00 :heavy_check_mark: AC 2 ms 4 MB
g++ example_01 :heavy_check_mark: AC 1 ms 4 MB
g++ fft_killer_00 :heavy_check_mark: AC 277 ms 26 MB
g++ fft_killer_01 :heavy_check_mark: AC 275 ms 26 MB
g++ fft_killer_02 :heavy_check_mark: AC 287 ms 26 MB
g++ fft_killer_03 :heavy_check_mark: AC 282 ms 26 MB
g++ fft_killer_04 :heavy_check_mark: AC 282 ms 26 MB
g++ fft_killer_05 :heavy_check_mark: AC 295 ms 26 MB
g++ fft_killer_06 :heavy_check_mark: AC 274 ms 26 MB
g++ fft_killer_07 :heavy_check_mark: AC 287 ms 26 MB
g++ fft_killer_08 :heavy_check_mark: AC 290 ms 26 MB
g++ fft_killer_09 :heavy_check_mark: AC 282 ms 26 MB
g++ max_ans_zero_00 :heavy_check_mark: AC 276 ms 26 MB
g++ max_random_00 :heavy_check_mark: AC 298 ms 26 MB
g++ max_random_01 :heavy_check_mark: AC 274 ms 26 MB
g++ medium_00 :heavy_check_mark: AC 4 ms 4 MB
g++ medium_01 :heavy_check_mark: AC 3 ms 4 MB
g++ medium_02 :heavy_check_mark: AC 4 ms 4 MB
g++ medium_all_zero_00 :heavy_check_mark: AC 3 ms 4 MB
g++ medium_pre_suf_zero_00 :heavy_check_mark: AC 2 ms 4 MB
g++ medium_pre_suf_zero_01 :heavy_check_mark: AC 2 ms 4 MB
g++ medium_pre_suf_zero_02 :heavy_check_mark: AC 2 ms 4 MB
g++ medium_pre_suf_zero_03 :heavy_check_mark: AC 2 ms 4 MB
g++ medium_pre_suf_zero_04 :heavy_check_mark: AC 2 ms 4 MB
g++ random_00 :heavy_check_mark: AC 240 ms 25 MB
g++ random_01 :heavy_check_mark: AC 262 ms 25 MB
g++ random_02 :heavy_check_mark: AC 127 ms 15 MB
g++ signed_overflow_00 :heavy_check_mark: AC 2 ms 4 MB
g++ small_00 :heavy_check_mark: AC 1 ms 4 MB
g++ small_01 :heavy_check_mark: AC 1 ms 4 MB
g++ small_02 :heavy_check_mark: AC 1 ms 4 MB
g++ small_03 :heavy_check_mark: AC 1 ms 4 MB
g++ small_04 :heavy_check_mark: AC 1 ms 4 MB
g++ small_05 :heavy_check_mark: AC 1 ms 4 MB
g++ small_06 :heavy_check_mark: AC 1 ms 4 MB
g++ small_07 :heavy_check_mark: AC 1 ms 4 MB
g++ small_08 :heavy_check_mark: AC 1 ms 4 MB
g++ small_09 :heavy_check_mark: AC 1 ms 4 MB
g++ small_10 :heavy_check_mark: AC 1 ms 4 MB
g++ small_11 :heavy_check_mark: AC 1 ms 4 MB
g++ small_12 :heavy_check_mark: AC 1 ms 4 MB
g++ small_13 :heavy_check_mark: AC 1 ms 4 MB
g++ small_14 :heavy_check_mark: AC 1 ms 4 MB
g++ small_15 :heavy_check_mark: AC 1 ms 4 MB
g++ small_and_large_00 :heavy_check_mark: AC 183 ms 24 MB
g++ small_and_large_01 :heavy_check_mark: AC 188 ms 24 MB
g++ small_and_large_02 :heavy_check_mark: AC 186 ms 22 MB
g++ small_and_large_03 :heavy_check_mark: AC 174 ms 22 MB
g++ unsigned_overflow_00 :heavy_check_mark: AC 2 ms 4 MB
clang++ all_same_00 :heavy_check_mark: AC 167 ms 26 MB
clang++ all_same_01 :heavy_check_mark: AC 270 ms 26 MB
clang++ all_same_02 :heavy_check_mark: AC 281 ms 26 MB
clang++ all_same_03 :heavy_check_mark: AC 272 ms 26 MB
clang++ example_00 :heavy_check_mark: AC 2 ms 4 MB
clang++ example_01 :heavy_check_mark: AC 1 ms 4 MB
clang++ fft_killer_00 :heavy_check_mark: AC 345 ms 26 MB
clang++ fft_killer_01 :heavy_check_mark: AC 302 ms 26 MB
clang++ fft_killer_02 :heavy_check_mark: AC 284 ms 26 MB
clang++ fft_killer_03 :heavy_check_mark: AC 283 ms 26 MB
clang++ fft_killer_04 :heavy_check_mark: AC 308 ms 26 MB
clang++ fft_killer_05 :heavy_check_mark: AC 286 ms 26 MB
clang++ fft_killer_06 :heavy_check_mark: AC 282 ms 26 MB
clang++ fft_killer_07 :heavy_check_mark: AC 279 ms 26 MB
clang++ fft_killer_08 :heavy_check_mark: AC 280 ms 26 MB
clang++ fft_killer_09 :heavy_check_mark: AC 273 ms 26 MB
clang++ max_ans_zero_00 :heavy_check_mark: AC 268 ms 26 MB
clang++ max_random_00 :heavy_check_mark: AC 289 ms 26 MB
clang++ max_random_01 :heavy_check_mark: AC 267 ms 26 MB
clang++ medium_00 :heavy_check_mark: AC 5 ms 4 MB
clang++ medium_01 :heavy_check_mark: AC 3 ms 4 MB
clang++ medium_02 :heavy_check_mark: AC 4 ms 4 MB
clang++ medium_all_zero_00 :heavy_check_mark: AC 3 ms 4 MB
clang++ medium_pre_suf_zero_00 :heavy_check_mark: AC 2 ms 4 MB
clang++ medium_pre_suf_zero_01 :heavy_check_mark: AC 2 ms 4 MB
clang++ medium_pre_suf_zero_02 :heavy_check_mark: AC 2 ms 4 MB
clang++ medium_pre_suf_zero_03 :heavy_check_mark: AC 2 ms 4 MB
clang++ medium_pre_suf_zero_04 :heavy_check_mark: AC 2 ms 4 MB
clang++ random_00 :heavy_check_mark: AC 226 ms 25 MB
clang++ random_01 :heavy_check_mark: AC 234 ms 25 MB
clang++ random_02 :heavy_check_mark: AC 119 ms 15 MB
clang++ signed_overflow_00 :heavy_check_mark: AC 2 ms 4 MB
clang++ small_00 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_01 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_02 :heavy_check_mark: AC 2 ms 4 MB
clang++ small_03 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_04 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_05 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_06 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_07 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_08 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_09 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_10 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_11 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_12 :heavy_check_mark: AC 2 ms 4 MB
clang++ small_13 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_14 :heavy_check_mark: AC 2 ms 4 MB
clang++ small_15 :heavy_check_mark: AC 1 ms 4 MB
clang++ small_and_large_00 :heavy_check_mark: AC 170 ms 24 MB
clang++ small_and_large_01 :heavy_check_mark: AC 168 ms 24 MB
clang++ small_and_large_02 :heavy_check_mark: AC 169 ms 22 MB
clang++ small_and_large_03 :heavy_check_mark: AC 163 ms 22 MB
clang++ unsigned_overflow_00 :heavy_check_mark: AC 2 ms 4 MB
Back to top page