题目描述

辣鸡多项式板子题不配拥有描述。

正解

先来康康三道模板题。

题目中那个一坨,其实相当于分别按顺序做上面的三个东西。

这题真的很没有营养,会就会,不会怎么想都写不了。

#include <bits/stdc++.h>
#define N 262144

using namespace std;

const int mod = 998244353, inv2 = 499122177;

int n;
int rev[N], lim, hib;
int A[N], B[N], C[N], D[N], popc[N];
int f[20][N], g[20][N], h[20][N];

inline int Add(int u, int v) { return (u += v) >= mod ? u - mod : u; }
inline void Inc(int &u, int v) { if((u += v) >= mod) u -= mod; }

inline int fpm(int x, int y) {
    int r = 1;
    while(y) {
        if(y & 1) r = 1LL * x * r % mod;
        x = 1LL * x * x % mod, y >>= 1;
    }
    return r;
}

inline int read() {
    int x = 0; char ch = getchar();
    while(!isdigit(ch)) ch = getchar();
    while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
    return x;
}

void getrev(int len) {
    lim = 1, hib = -1;
    while(lim < len) lim <<= 1, ++hib;
    for(int i = 0; i < lim; ++i)
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << hib);
}

void fwtOr(int *a, bool type) {
    for(int mid = 1; mid < lim; mid <<= 1)
        for(int i = 0; i < lim; i += (mid << 1))
            for(int j = 0; j < mid; ++j)
                if(type) Inc(a[i + mid + j], a[i + j]);
                else Inc(a[i + mid + j], mod - a[i + j]);
}
void fwtXor(int *a, bool type) {
    static int x, y;
    for(int mid = 1; mid < n; mid <<= 1)
        for(int len = mid << 1, i = 0; i < n; i += len)
            for(int j = 0; j < mid; ++j) {
                x = a[i + j], y = a[i + mid + j];
                a[i + j] = Add(x, y), a[i + mid + j] = Add(x, mod - y);
                if(!type) a[i + j] = 1LL * inv2 * a[i + j] % mod,
                          a[i + mid + j] = 1LL * inv2 * a[i + mid + j] % mod;
            }
}
void NTT(int *a, bool type) {
    for(int i = 0; i < lim; ++i)
        if(i < rev[i])
            swap(a[i], a[rev[i]]);
    static int x, y;
    for(int mid = 1; mid < lim; mid <<= 1) {
        int len = mid << 1, wn = fpm(3, (mod - 1) / len);
        for(int i = 0; i < lim; i += len)
            for(int j = 0, w = 1; j < mid; ++j, w = 1LL * w * wn % mod) {
                x = a[i + j], y = 1LL * w * a[i + mid + j] % mod;
                a[i + j] = Add(x, y), a[i + mid + j] = Add(x, mod - y);
            }
    }
    if(!type) {
        reverse(a + 1, a + lim);
        int inv = fpm(lim, mod - 2);
        for(int i = 0; i < lim; ++i)
            a[i] = 1LL * inv * a[i] % mod;
    }
}

int main() {
    n = read(), ++n;
    getrev(n + n - 1);
    for(int i = 0; i < lim; ++i) popc[i] = popc[i >> 1] + (i & 1);
    for(int i = 0; i < n; ++i) A[i] = read(), f[popc[i]][i] = A[i];
    for(int i = 0; i < n; ++i) B[i] = read(), g[popc[i]][i] = B[i];
    for(int i = 0; i < n; ++i) C[i] = read();
    for(int i = 0; i < n; ++i) D[i] = read();

    for(int i = 0; i <= 17; ++i)
        fwtOr(f[i], true), fwtOr(g[i], true);
    for(int sa = 0; sa <= 17; ++sa)
        for(int sb = 0; sb + sa <= 17; ++sb)
            for(int i = 0; i < lim; ++i)
                h[sa + sb][i] = (h[sa + sb][i] + 1LL * f[sa][i] * g[sb][i]) % mod;
    for(int i = 0; i <= 17; ++i)
        fwtOr(h[i], false);
    for(int i = 0; i < lim; ++i)
        A[i] = h[popc[i]][i];

    NTT(A, true), NTT(C, true);
    for(int i = 0; i < lim; ++i)
        A[i] = 1LL * A[i] * C[i] % mod;
    NTT(A, false);

    fwtXor(A, true), fwtXor(D, true);
    for(int i = 0; i < lim; ++i)
        A[i] = 1LL * A[i] * D[i] % mod;
    fwtXor(A, false);

    int Q = read();
    while(Q--) printf("%d\n", A[read()]);
    return 0;
}