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
|
#include <cstdio> #include <cstring> #include <algorithm>
using namespace std;
const int mod = 998244353; const int g = 3; const int maxn = 100010;
int (int x, int y) { int ret = 1; while (y) { if (y & 1) { ret = 1LL*ret*x%mod; } x = 1LL*x*x%mod; y >>= 1; } return ret; }
int w_a[maxn*4], w_b[maxn*4], w_c[maxn*4], rev[maxn*4];
int n = 0;
struct poly { int *a, len; poly (int l = 0) { a = new int[l]; len = l; for (int i = 0; i < l; i++) { a[i] = 0; } } };
void ntt(int *a, int t, int ty) { int len = (1 << t); for (int i = 1; i < len; i++) rev[i] = (rev[i>>1]>>1)|((i&1)<<(t-1)); for (int i = 0; i < len; i++) if (rev[i] > i) swap(a[rev[i]], a[i]); for (int l = 2; l <= len; l <<= 1) { int wn = qpow(g, (mod-1)/l); for (int s = 0; s < len; s += l) { int w = 1; for (int i = s; i < (s + (l >> 1)); i++) { int v1 = a[i], v2 = 1LL*a[i+(l>>1)]*w%mod; a[i] = (v1+v2) % mod; a[i+(l>>1)] = (v1-v2+mod) % mod; w = 1LL*w*wn%mod; } } } if (ty == -1) { for (int i = 1; i < len/2; i++) swap(a[i], a[len-i]); int r = qpow(len, mod-2); for (int i = 0; i < len; i++) a[i] = 1LL*a[i]*r%mod; } }
poly operator*(poly A, poly B) { poly ret(A.len + B.len - 1); int t = 0; while ((1<<t) < ret.len) t ++; for (int i = 0; i < (1<<t); i++) w_a[i] = w_b[i] = 0; for (int i = 0; i < A.len; i++) w_a[i] = A.a[i]; for (int i = 0; i < B.len; i++) w_b[i] = B.a[i]; ntt(w_a, t, 1); ntt(w_b, t, 1); for (int i = 0; i < (1<<t); i++) w_c[i] = 1LL*w_a[i]*w_b[i]%mod; ntt(w_c, t, -1); for (int i = 0; i < ret.len; i++) ret.a[i] = w_c[i]; return ret; }
poly inverse(poly A) { if (A.len == 1) { poly ret(1); ret.a[0] = qpow(A.a[0], mod-2); return ret; } int nlen = (A.len+1)/2; poly nA(nlen); for (int i = 0; i < nlen; i++) nA.a[i] = A.a[i]; poly r = inverse(nA); poly tmp = A*r; tmp.len = A.len; for (int i = 0; i < tmp.len; i++) tmp.a[i] = (-tmp.a[i]+mod)%mod; tmp.a[0] = (tmp.a[0]+2) % mod; poly ret = r*tmp; ret.len = A.len; return ret; }
int main() { scanf("%d", &n); poly F(n); for (int i = 0; i < n; i++) scanf("%d", &F.a[i]); poly G = inverse(F); for (int i = 0; i < n; i++) printf("%d ", G.a[i]); printf("n"); return 0; }
|
近期评论