namespace poly

#include <iostream>

using i64 = long long;

namespace poly {
    const i64 MOD = 998244353, g = 3;
    const int MaxBit = 22, MaxLen = 1 << MaxBit;
    const int N = MaxLen | 7;
    typedef i64 polyT[N];
    
    i64 pow(i64 a, i64 k);

    int rev[N];
    i64 w[N];
    struct poly_ {
        poly_() {
            for (int i = 1; i < MaxLen; ++i)
                rev[i] = rev[i >> 1] >> 1 | (i & 1 ? MaxLen >> 1 : 0);
            w[MaxLen >> 1] = 1;
            i64 x = pow(g, (MOD - 1) / MaxLen);
            for (int i = (MaxLen >> 1) + 1; i < MaxLen; ++i) w[i] = w[i - 1] * x % MOD;
            for (int i = (MaxLen >> 1) - 1; ~i; --i) w[i] = w[i << 1];
        }
    } p_;
    
    void ntt(i64 a[], int n, int on);
    void mul(i64 a[], int n, i64 b[], int m, i64 c[]);
    
    void ntt(i64 a[], int n, int on) {
        static i64 f[N], x;
        int s = 0; while (n << s < MaxLen) ++s;
        for (int i = 0; i < n; ++i) f[rev[i] >> s] = a[i];
        for (int l = 1; l < n; l <<= 1)
            for (int i = 0; i < n; i += l << 1)
                for (int j = 0; j < l; ++j)
                    x = (f[i | j | l] %= MOD) * w[j | l] % MOD,
                    f[i | j | l] = f[i | j] - x, f[i | j] += x;
        if (on == 1)
            for (int i = 0; i < n; ++i) a[i] = f[i] % MOD;
        else {
            a[0] = f[0] % MOD * (x = pow(n, MOD - 2)) % MOD;
            for (int i = 1; i < n; ++i) a[i] = f[n - i] % MOD * x % MOD;
        }
    }
    void mul(i64 a[], int n, i64 b[], int m, i64 c[]) {
        for (n = m = n + m - 1; n ^ (n & -n); n += n & -n);
        ntt(a, n, 1), ntt(b, n, 1);
        for (int i = 0; i < n; ++i) c[i] = a[i] * b[i] % MOD;
        ntt(c, n, -1);
    }
    
    i64 pow(i64 a, i64 k) {
        i64 t = 1;
        for (; k; a = a * a % MOD, k >>= 1) if (k & 1) t = t * a % MOD;
        return t;
    }
};
using poly::MOD;

int main() {
    static int n, m;
    static poly::polyT a, b, c;
    
    scanf("%d%d", &n, &m), ++n, ++m;
    for (int i = 0; i < n; ++i) scanf("%lld", a + i);
    for (int i = 0; i < m; ++i) scanf("%lld", b + i);
    poly::mul(a, n, b, m, c);
    for (int i = 0; i < n + m - 1; ++i) printf("%lld ", (c[i] + MOD) % MOD);
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Ryedii-blog/p/12490175.html
今日推荐