提交记录 19918


用户 题目 状态 得分 用时 内存 语言 代码长度
liuziao 1002i. 【模板题】多项式乘法 Accepted 100 42.187 ms 5340 KB C++17 5.21 KB
提交时间 评测时间
2023-08-13 18:24:43 2023-08-13 18:24:47
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <iostream>
#include <vector>

// #define int int64_t

using i64 = int64_t;

const int kMaxN = 4e5 + 5, kMod = 998244353;

int polyg[kMaxN];
bool inited;

int qpow(int bs, int idx = kMod - 2) {
  int ret = 1;
  for (; idx; idx >>= 1, bs = (i64)bs * bs % kMod)
    if (idx & 1)
      ret = (i64)ret * bs % kMod;
  return ret;
}

inline int add(int x, int y) { return (x + y >= kMod ? x + y - kMod : x + y); }
inline int sub(int x, int y) { return (x >= y ? x - y : x - y + kMod); }
inline void inc(int &x, int y) { (x += y) >= kMod ? x -= kMod : x; }
inline void dec(int &x, int y) { (x -= y) < 0 ? x += kMod : x; }

void prework(int n = (kMaxN - 5) / 2) {
  inited = 1;
  int c = 0;
  for (; (1 << c) <= n; ++c) {}
  c = std::min(c - 1, 21);
  polyg[0] = 1, polyg[1 << c] = qpow(31, 1 << 21 - c);
  for (int i = c; i; --i)
    polyg[1 << i - 1] = (i64)polyg[1 << i] * polyg[1 << i] % kMod;
  for (int i = 1; i < (1 << c); ++i) 
    polyg[i] = (i64)polyg[i & (i - 1)] * polyg[i & -i] % kMod;
}

int getlen(int n) {
  int len = 1;
  for (; len <= n; len <<= 1) {}
  return len;
}

struct Poly : std::vector<int> {
  using vector::vector;
  using vector::operator [];

  friend Poly operator -(Poly a) {
    static Poly c;
    c.resize(a.size());
    for (int i = 0; i < c.size(); ++i)
      c[i] = sub(0, c[i]);
    return c;
  }
  friend Poly operator +(Poly a, Poly b) {
    static Poly c;
    c.resize(std::max(a.size(), b.size()));
    for (int i = 0; i < c.size(); ++i)
      c[i] = add((i < a.size() ? a[i] : 0), (i < b.size() ? b[i] : 0));
    return c;
  }
  friend Poly operator -(Poly a, Poly b) {
    static Poly c;
    c.resize(std::max(a.size(), b.size()));
    for (int i = 0; i < c.size(); ++i)
      c[i] = sub((i < a.size() ? a[i] : 0), (i < b.size() ? b[i] : 0));
    return c;
  }
  friend void dif(Poly &a, int len) {
    for (int l = len; l != 1; l >>= 1) {
      int m = l / 2;
      for (int i = 0, k = 0; i < len; i += l, ++k) {
        for (int j = 0; j < m; ++j) {
          int tmp = (i64)a[i + j + m] * polyg[k] % kMod;
          a[i + j + m] = sub(a[i + j], tmp);
          inc(a[i + j], tmp);
        }
      }
    }
  }
  friend void dit(Poly &a, int len) {
    for (int l = 2; l <= len; l <<= 1) {
      int m = l / 2;
      for (int i = 0, k = 0; i < len; i += l, ++k) {
        for (int j = 0; j < m; ++j) {
          int tmp = a[i + j + m];
          a[i + j + m] = (i64)sub(a[i + j], tmp) * polyg[k] % kMod;
          inc(a[i + j], tmp);
        }
      }
    }
    int invl = qpow(len);
    for (int i = 0; i < len; ++i)
      a[i] = (i64)a[i] * invl % kMod;
    std::reverse(a.begin() + 1, a.begin() + len);
  }
  friend Poly operator *(Poly a, Poly b) {
    if (!inited) prework();
    int n = a.size() + b.size() - 1, len = getlen(n);
    a.resize(len), b.resize(len);
    dif(a, len), dif(b, len);
    for (int i = 0; i < len; ++i)
      a[i] = (i64)a[i] * b[i] % kMod;
    dit(a, len);
    a.resize(n);
    return a;
  }
  friend Poly operator *(Poly a, int b) {
    static Poly c;
    c = a;
    for (auto &x : c) x = (i64)x * b % kMod;
    return c;
  }
  friend Poly operator *(int a, Poly b) {
    static Poly c;
    c = b;
    for (auto &x : c) x = (i64)x * a % kMod;
    return c;
  }
  friend void operator *=(Poly &a, Poly b) {
    if (!inited) prework();
    int n = a.size() + b.size() - 1, len = getlen(n);
    // std::cerr << len << '\n';
    // for (auto x : a) std::cerr << x << ' ';
    // std::cerr << '\n';
    // for (auto x : b) std::cerr << x << ' ';
    // std::cerr << '\n';
    a.resize(len), b.resize(len);
    dif(a, len), dif(b, len);
    for (int i = 0; i < len; ++i)
      a[i] = (i64)a[i] * b[i] % kMod;
    dit(a, len);
    a.resize(n);
  }
  friend Poly Inv(Poly a) {
    Poly G = {qpow(a[0])}, H;
    std::vector<int> vec;
    for (int i = a.size(); i != 1; i = (i + 1) / 2) vec.emplace_back(i);
    vec.emplace_back(1);
    std::reverse(vec.begin(), vec.end());
    for (auto n : vec) {
      auto tmp = a;
      tmp.resize(n);
      H = G, G = 2 * H;
      G.resize(n);
      int len = getlen(n * 2 + 2);
      if (!inited) prework();
      dif(tmp, len), dif(H, len);
      for (int i = 0; i < len; ++i)
        H[i] = (i64)tmp[i] * H[i] % kMod * H[i] % kMod;
      dit(H, len);
      for (int i = 0; i < n; ++i)
        G[i] = sub(G[i], H[i]);
    }
    return G;
  }
  friend Poly Ln(Poly a) {
    int n = a.size();
    Poly b, c, tmp;
    if (n == 1) {
      b.resize(a.size());
      return b;
    }
    b.resize(n - 1);
    for (int i = 1; i < n; ++i)
      b[i - 1] = (i64)i * a[i] % kMod;
    tmp = Inv(a);
    b = b * tmp;
    c.resize(n);
    for (int i = 0; i < n - 1; ++i)
      c[i + 1] = (i64)b[i] * qpow(i + 1) % kMod;
    return c;
  }
};

void dickdreamer() {
  int n, m;
  Poly a, b;
  std::cin >> n >> m;
  a.resize(n + 1), b.resize(m + 1);
  for (auto &x : a) std::cin >> x;
  for (auto &x : b) std::cin >> x;
  a *= b;
  for (auto x : a) std::cout << x << ' ';
}

int32_t main() {
#ifdef ORZXKR
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
#endif
  std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
  int T = 1;
  // std::cin >> T;
  while (T--) dickdreamer();
  // std::cerr << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
  return 0;
}

CompilationN/AN/ACompile OKScore: N/A

Subtask #1 Testcase #1325.06 us580 KBAcceptedScore: 0

Subtask #1 Testcase #242.187 ms5 MB + 140 KBAcceptedScore: 0

Subtask #1 Testcase #319.566 ms2 MB + 632 KBAcceptedScore: 100

Subtask #1 Testcase #419.51 ms2 MB + 228 KBAcceptedScore: 0

Subtask #1 Testcase #5329.03 us580 KBAcceptedScore: 0

Subtask #1 Testcase #6325.1 us580 KBAcceptedScore: 0

Subtask #1 Testcase #7324.95 us580 KBAcceptedScore: 0

Subtask #1 Testcase #837.835 ms4 MB + 764 KBAcceptedScore: 0

Subtask #1 Testcase #937.813 ms4 MB + 628 KBAcceptedScore: 0

Subtask #1 Testcase #1033.358 ms4 MB + 224 KBAcceptedScore: 0

Subtask #1 Testcase #1142.121 ms5 MB + 220 KBAcceptedScore: 0

Subtask #1 Testcase #1239.019 ms4 MB + 100 KBAcceptedScore: 0

Subtask #1 Testcase #13324.13 us580 KBAcceptedScore: 0


Judge Duck Online | 评测鸭在线
Server Time: 2024-12-05 10:38:41 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠