1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
| #include <iostream> #include <algorithm> #include <cstring> #include <cmath> #include <cstdio>
using std::acos; using std::cos; using std::sin; using std::reverse; using std::swap;
typedef long long ll;
const int maxn = 262150; const int mask15 = 32767; const double pi = acos(-1);
struct comp { double r, i; comp(double r_ = 0.0, double i_ = 0.0):r(r_),i(i_){} comp operator + (const comp &rhs) { return comp(r + rhs.r, i + rhs.i); } comp operator - (const comp &rhs) { return comp(r - rhs.r, i - rhs.i); } comp operator * (const comp &rhs) { return comp(r * rhs.r - i * rhs.i, r * rhs.i + i * rhs.r); } }; comp conj(const comp &c) { return comp(c.r, -c.i); }
int nn, mm, N, L; int mod; int rev[maxn]; comp omega[maxn];
inline void init() { for(int i = 0; i < N; ++i) omega[i] = comp(cos(2 * pi * i / N), sin(2 * pi * i / N)), rev[i] = rev[i >> 1] >> 1 | ((i & 1) << (L - 1)); } inline void FFT(int n, comp *a) { for(int i = 0; i < n; ++i) if(i < rev[i]) swap(a[i], a[rev[i]]); for(int i = 2, j = (n >> 1); i <= n; i <<= 1, j >>= 1) for(int k = 0; k < n; k += i) { comp *l = a + k, *r = a + k + (i >> 1), *w = omega; for(int p = 0; p < (i >> 1); ++p) { comp t = (*r) * (*w); *r = (*l) - t, *l = (*l) + t; ++l; ++r; w += j; } } } inline void solve(int *x, int *y, int *z) { for(int i = 0; i < N; ++i) x[i] = (int)((ll)(x[i] + mod) % mod), y[i] = (int)((ll)(y[i] + mod) % mod); static comp a[maxn], b[maxn]; static comp dft1[maxn], dft2[maxn], dft3[maxn], dft4[maxn];
for(int i = 0; i < N; ++i) a[i] = comp(x[i] & mask15, x[i] >> 15), b[i] = comp(y[i] & mask15, y[i] >> 15); FFT(N, a); FFT(N, b); for(int i = 0; i < N; ++i) { int j = (N - i) & (N - 1); static comp da, db, dc, dd; da = (a[i] + conj(a[j])) * comp(0.5, 0.0); db = (a[i] - conj(a[j])) * comp(0.0, -0.5); dc = (b[i] + conj(b[j])) * comp(0.5, 0.0); dd = (b[i] - conj(b[j])) * comp(0.0, -0.5); dft1[j] = da * dc; dft2[j] = da * dd; dft3[j] = db * dc; dft4[j] = db * dd; } for(int i = 0; i < N; ++i) a[i] = dft1[i] + dft2[i] * comp(0, 1); for(int i = 0; i < N; ++i) b[i] = dft3[i] + dft4[i] * comp(0, 1); FFT(N, a); FFT(N, b); for(int i = 0; i < N; ++i) { int da = (ll)(a[i].r / N + 0.5) % mod; int db = (ll)(a[i].i / N + 0.5) % mod; int dc = (ll)(b[i].r / N + 0.5) % mod; int dd = (ll)(b[i].i / N + 0.5) % mod; z[i] = (da + ((ll)(db + dc) << 15) + ((ll)dd << 30)) % mod; } }
int main() { scanf("%d%d%d", &nn, &mm, &mod); nn++; mm++; static int A[maxn], B[maxn], C[maxn]; for(int i = 0; i < nn; ++i) scanf("%d", &A[i]); for(int i = 0; i < mm; ++i) scanf("%d", &B[i]); L = 0; for(; (1 << L) < nn + mm - 1; ++L); N = (1 << L); init(); solve(A, B, C); for(int i = 0; i < nn + mm - 1; ++i) C[i] = (C[i] + mod) % mod, printf("%d ", C[i]); return 0; }
|