void Conv (LL a[], LL b[], int n) { NTT (a, n, 1); NTT (b, n, 1); for (int i = 0; i < n; i++) a[i] = a[i] * b[i] % P; NTT (a, n, -1); }
int main() { for (N=1; N<na||N<nb; N<<=1); N<<=1; for (int i=na;i<N;i++) a[i]=b[i]=0; W[0][0]=W[1][0]=1; for (int i=1,x=Pow(g,(P-1)/N),y=Pow(x,P-2); i<N; i++) W[0][i]=(LL)x*W[0][i-1]%P,W[1][i]=(LL)y*W[1][i-1]%P; change(); NTT(a,0),NTT(b,0); for (int i=0;i<N;i++) a[i]=(LL)a[i]*b[i]%P; NTT(a,1); }
void mul(int *A, int *B, int *C, int n) { static int A1[maxN], B1[maxN], C1[maxN]; int N = init(n); memset(A1, 0, sizeof(*A1) * N); memset(B1, 0, sizeof(*B1) * N); memset(C1, 0, sizeof(*C1) * N); memset(C, 0, sizeof(*C) * N); memcpy(A1, A, sizeof(*A) * n); memcpy(B1, B, sizeof(*B) * n); NTT(A1, P1, E1, N); NTT(B1, P1, E1, N); for (int i = 0; i < N; ++i) C1[i] = (LL)A1[i] * B1[i] % P1; NTT(C1, P1, F1, N); for (int i = 0; i < N; ++i) C1[i] = (LL)C1[i] * I1 % P1; NTT(A, P2, E2, N); NTT(B, P2, E2, N); for (int i = 0; i < N; ++i) C[i] = (LL)A[i] * B[i] % P2; NTT(C, P2, F2, N); for (int i = 0; i < N; ++i) C[i] = (LL)C[i] * I2 % P2; for (int i = 0; i < N; ++i) C[i] = CRT(C1[i], C[i]); for (int i = n; i < N; ++i) C[i] = 0; }