【Luogu4238】【模板】任意模数NTT

/************************************************
 * Au: Hany01
 * Date: May 25th, 2018
 * Prob: 任意模数NTT
 * Email: [email protected]
************************************************/

#include<bits/stdc++.h>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
#define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
#define rep(i, j) for (register int i = 0, i##_end_ = (j); i < i##_end_; ++ i)
#define For(i, j, k) for (register int i = (j), i##_end_ = (k); i <= i##_end_; ++ i)
#define Fordown(i, j, k) for (register int i = (j), i##_end_ = (k); i >= i##_end_; -- i)
#define Set(a, b) memset(a, b, sizeof(a))
#define Cpy(a, b) memcpy(a, b, sizeof(a))
#define x first
#define y second
#define pb(a) push_back(a)
#define mp(a, b) make_pair(a, b)
#define ALL(a) (a).begin(), (a).end()
#define SZ(a) ((int)(a).size())
#define INF (0x3f3f3f3f)
#define INF1 (2139062143)
#define Mod (1000000007)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define y1 wozenmezhemecaia

template <typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; }
template <typename T> inline bool chkmin(T &a, T b) { return b < a ? a = b, 1 : 0; }

inline int read()
{
    register int _, __; register char c_;
    for (_ = 0, __ = 1, c_ = getchar(); c_ < '0' || c_ > '9'; c_ = getchar()) if (c_ == '-') __ = -1;
    for ( ; c_ >= '0' && c_ <= '9'; c_ = getchar()) _ = (_ << 1) + (_ << 3) + (c_ ^ 48);
    return _ * __;
}

const long double Pi = acos(-1.);
const int maxn = 800005;

struct Complex
{
    long double x, y;
}a[maxn], b[maxn], c[maxn], d[maxn];
inline Complex operator + (const Complex &A, const Complex &B) { return (Complex){A.x + B.x, A.y + B.y}; }
inline Complex operator - (const Complex &A, const Complex &B) { return (Complex){A.x - B.x, A.y - B.y}; }
inline Complex operator * (const Complex &A, const Complex &B) { return (Complex){A.x * B.x - A.y * B.y, A.x * B.y + A.y * B.x}; }
int A[maxn], B[maxn], n1, n2, N, rev[maxn], cnt, p, n;

inline void FFT(Complex* a, int type)
{
    rep(i, N) if (i < rev[i]) swap(a[i], a[rev[i]]);
    for (int i = 2; i <= N; i <<= 1)
    {
        Complex wn = (Complex){cos(2 * Pi / i), sin(2 * Pi / i * type)};
        for (int j = 0; j <= N; j += i)
        {
            Complex w = (Complex){1, 0};
            rep(k, i >> 1)
            {
                Complex x = a[k + j], y = a[k + j + (i >> 1)] * w;
                a[k + j] = x + y, a[k + j + (i >> 1)] = x - y;
                w = w * wn;
            }
        }
    }
    if (type == -1) rep(i, N) a[i].x = a[i].x / N;
}

int main()
{
#ifdef hany01
    File("exNTT");
#endif

    n1 = read(), n2 = read(), p = read(), n = n1 + n2 + 1;
    rep(i, n1 + 1) A[i] = read();
    rep(i, n2 + 1) B[i] = read();
    for (N = 1; N <= n; N <<= 1, ++ cnt) ;
    rep(i, N) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (cnt - 1));

    rep(i, N)
        a[i].x = A[i] >> 15, b[i].x = A[i] & 32767,
        c[i].x = B[i] >> 15, d[i].x = B[i] & 32767;
    FFT(a, 1), FFT(b, 1), FFT(c, 1), FFT(d, 1);
    rep(i, N) {
        Complex ta = a[i], tb = b[i], tc = c[i], td = d[i];
        a[i] = ta * tc, b[i] = ta * td + tb * tc, c[i] = tb * td;
    }
    FFT(a, -1), FFT(b, -1), FFT(c, -1);
    rep(i, n)
        printf("%lld ", ((LL)(a[i].x + .5) % p * (1ll << 30) % p + (LL)(b[i].x + .5) % p * (1ll << 15) % p + (LL)(c[i].x + .5) % p) % p);

    return 0;
}
//采得百花成蜜后,为谁辛苦为谁甜。
//    -- 罗隐《蜂》

猜你喜欢

转载自blog.csdn.net/hhaannyyii/article/details/80457309