为啥我的 FFT 结果除了常数项都是反的
查看原帖
为啥我的 FFT 结果除了常数项都是反的
253946
raincity楼主2024/1/19 22:53
#include <bits/stdc++.h>

#define ALL(x) begin(x), end(x)
#define EVAL(x) #x " = " << (x)

using std::cin, std::cout;
using std::pair, std::tuple;

using i64 = int64_t;
using f64 = long double;
using str = std::string;

template <typename T>
using vec = std::vector<T>;

template <typename T, size_t n>
using arr = std::array<T, n>;

constexpr int mod = 998244353;
namespace Arith {
inline auto fix(int x) { return x + (x >> 31 & mod); }
inline void sub(int& x, int y) { x = fix(x - y); }
inline auto norm(int x) { return x >= mod ? x - mod : x; }
inline void add(int& x, int y) { x = norm(x + y); }
auto power(i64 a, int b) -> i64 {
  i64 ans = 1;
  for (; b; b >>= 1) {
    if (b & 1) ans = ans * a % mod;
    a = a * a % mod;
  }
  return ans;
}
inline auto inverse(i64 a) { return power(a, mod - 2); }
}  // namespace Arith

namespace Poly {
using Poly = vec<int>;

constexpr int g = 3, siz = 1 << 21;

const auto w = []() -> arr<int, siz> {
  arr<int, siz> w;
  for (int i = 1; i < siz; i *= 2) {
    i64 x = Arith::power(g, (mod - 1) / (i * 2));
    w[i] = 1;
    for (int j = i + 1; j < i * 2; ++j) w[j] = w[j - 1] * x % mod;
  }
  return w;
}();

void dif(Poly& f) {
  int n = f.size();
  for (int i = n; i >>= 1;)
    for (int j = 0; j < n; j += i * 2)
      for (int k = 0; k < i; ++k) {
        int &x = f[j + k], y = f[i + j + k];
        f[i + j + k] = i64{w[i + k]} * Arith::fix(x - y) % mod;
        Arith::add(x, y);
      }
}

void dit(Poly& f) {
  int n = f.size();
  for (int i = 1; i < n; i *= 2)
    for (int j = 0; j < n; j += i * 2)
      for (int k = 0; k < i; ++k) {
        int &x = f[j + k], y = i64{f[i + j + k]} * w[i + k] % mod;
        f[i + j + k] = Arith::fix(x - y), Arith::add(x, y);
      }
  int inv = Arith::inverse(n);
  for (int& i : f) i = i64{i} * inv % mod;
}
}  // namespace Poly

inline auto bit_log(int n) { return n == 0 ? -1 : 31 ^ __builtin_clz(n); }

auto main() -> int {
  std::ios_base::sync_with_stdio(false), cin.tie(nullptr);

  int n = 0, m = 0;
  cin >> n >> m;

  int len = 1 << (bit_log(n + m) + 1);
  Poly::Poly f(len), g(len);
  for (int i = 0; i <= n; ++i) cin >> f[i];
  for (int i = 0; i <= m; ++i) cin >> g[i];

  Poly::dif(f);
  Poly::dif(g);
  for (int i = 0; i < len; ++i) f[i] = i64{f[i]} * g[i] % mod;
  Poly::dit(f);
  std::reverse(1 + ALL(f)); // Notice this!
  for (int i = 0; i <= n + m; ++i) cout << f[i] << " \n"[i == n + m];
}
2024/1/19 22:53
加载中...