提交记录 8508


用户 题目 状态 得分 用时 内存 语言 代码长度
memset0 1002i. 【模板题】多项式乘法 Accepted 100 32.273 ms 8284 KB C++ 4.17 KB
提交时间 评测时间
2019-02-21 12:35:37 2020-08-01 01:19:59
// =================================
//   author: memset0
//   date: 2019.02.17 17:16:00
//   website: https://memset0.cn/
// =================================
#include <bits/stdc++.h>
#define ll long long
#define poly std::vector <int>
#define for_each(i, a) for (int i = 0, __lim = a.size(); i < __lim; ++i)
namespace ringo {
template <class T> inline void read(T &x) {
    x = 0; register char c = getchar(); register bool f = 0;
    while (!isdigit(c)) f ^= c == '-', c = getchar();
    while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
    if (f) x = -x;
}
template <class T> inline void print(T x) {
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) print(x / 10);
    putchar('0' + x % 10);
}
template <class T> inline void print(T x, char c) { print(x), putchar(c); }
inline void print(const poly &a) { for_each(i, a) print(a[i], " \n"[i == __lim - 1]); }
inline void read(poly &a, int n) { for (int i = 0, x; i < n; i++) read(x), a.push_back(x); }

const int N = 1e6 + 10, M = 8e6 + 10, mod = 998244353;
int n;

namespace poly_namespace {
    const int SIZE = sizeof(int);
    int w[M], rev[M];
    inline poly resize(poly f, int n) { return f.resize(n), f; }
    inline int dec(int a, int b) { a -= b; return a < 0 ? a + mod : a; }
    inline int sub(int a, int b) { a += b; return a >= mod ? a - mod : a; }
    inline int inv(int x) { return x < 2 ? 1 : (ll)(mod - mod / x) * inv(mod % x) % mod; }
    inline int fpow(int a, int b) { int s = 1; for (; b; b >>= 1, a = (ll)a * a % mod) if (b & 1) s = (ll)s * a % mod; return s; }
    inline poly operator + (poly f, int a) { f[0] = sub(f[0], a); return f; }
    inline poly operator + (int a, poly f) { f[0] = sub(a, f[0]); return f; }
    inline poly operator - (poly f, int a) { f[0] = dec(f[0], a); return f; }
    inline poly operator - (int a, poly f) { for_each(i, f) f[i] = dec(0, f[i]); f[0] = sub(a, f[0]); return f; }
    inline poly operator * (poly f, int a) { for_each(i, f) f[i] = (ll)f[i] * a % mod; return f; }
    inline poly operator * (int a, poly f) { for_each(i, f) f[i] = (ll)f[i] * a % mod; return f; }
    inline poly operator + (poly f, const poly &g) {
        f.resize(std::max(f.size(), g.size()));
        for_each(i, f) f[i] = sub(i < f.size() ? f[i] : 0, i < g.size() ? g[i] : 0);
        return f;
    }
    inline poly operator - (poly f, const poly &g) {
        f.resize(std::max(f.size(), g.size()));
        for_each(i, f) f[i] = dec(i < f.size() ? f[i] : 0, i < g.size() ? g[i] : 0);
        return f;
    }
    void ntt(int *a, int lim) {
        for (int i = 0; i < lim; i++) if (i < rev[i]) std::swap(a[i], a[rev[i]]);
        for (int len = 1; len < lim; len <<= 1)
            for (int i = 0; i < lim; i += (len << 1))
                for (int j = 0; j < len; j++) {
                    int x = a[i + j], y = (ll)w[j + len] * a[i + j + len] % mod;
                    a[i + j] = sub(x, y), a[i + j + len] = dec(x, y);
                }
    }
    int init(int len) {
        int lim = 1, k = 0; while (lim < len) lim <<= 1, ++k;
        for (int i = 0; i < lim; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (k - 1));
        return lim;
    }
    void main_init(int lim) {
        for (int len = 1, wn, __lim = std::min(lim + 2, M); len < __lim; len <<= 1) {
            wn = fpow(3, (mod - 1) / (len << 1)), w[len] = 1;
            for (int i = 1; i < len; i++) w[i + len] = (ll)w[i + len - 1] * wn % mod;
        }
    }
    inline poly operator * (const poly &f, const poly &g) {
        static int a[M], b[M];
        int lim = init(f.size() + g.size() - 1), inv_lim = inv(lim); poly h;
        memset(&a[f.size()], 0, (lim - f.size()) * SIZE); for_each(i, f) a[i] = f[i];
        memset(&b[g.size()], 0, (lim - g.size()) * SIZE); for_each(i, g) b[i] = g[i];
        ntt(a, lim), ntt(b, lim);
        for (int i = 0; i < lim; i++) a[i] = (ll)a[i] * b[i] % mod;
        std::reverse(a + 1, a + lim), ntt(a, lim);
        for (int i = 0, l = f.size() + g.size() - 1; i < l; i++) h.push_back((ll)a[i] * inv_lim % mod);
        return h;
    }
} using namespace poly_namespace;

void main() {
    int n, m; poly A, B;
    read(n), read(m), main_init(n + m);
    read(A, n + 1), read(B, m + 1);
    print(A * B);
}

} signed main() { return ringo::main(), 0; }

CompilationN/AN/ACompile OKScore: N/A

Subtask #1 Testcase #136.34 us52 KBAcceptedScore: 0

Subtask #1 Testcase #231.128 ms8 MB + 12 KBAcceptedScore: 100

Subtask #1 Testcase #311.776 ms3 MB + 612 KBAcceptedScore: 0

Subtask #1 Testcase #411.842 ms3 MB + 460 KBAcceptedScore: 0

Subtask #1 Testcase #536.7 us52 KBAcceptedScore: 0

Subtask #1 Testcase #636.91 us52 KBAcceptedScore: 0

Subtask #1 Testcase #735.83 us52 KBAcceptedScore: 0

Subtask #1 Testcase #829.391 ms7 MB + 496 KBAcceptedScore: 0

Subtask #1 Testcase #929.36 ms7 MB + 496 KBAcceptedScore: 0

Subtask #1 Testcase #1027.557 ms6 MB + 980 KBAcceptedScore: 0

Subtask #1 Testcase #1132.273 ms8 MB + 92 KBAcceptedScore: 0

Subtask #1 Testcase #1224.216 ms6 MB + 996 KBAcceptedScore: 0

Subtask #1 Testcase #1334.67 us52 KBAcceptedScore: 0


Judge Duck Online | 评测鸭在线
Server Time: 2026-04-06 15:16:35 | Loaded in 1 ms | Server Status
个人娱乐项目,仅供学习交流使用 | 捐赠