[ECNU] 3314. 多项式展开 (1)
作者:互联网
https://acm.ecnu.edu.cn/problem/3314/
二项式展开得:
$$
\begin{aligned}
&\sum_{i=0}^{n}a_i(x+A)^i \\
=&\sum_{i=0}^{n}a_i\sum_{j=0}^{i}{i \choose j} x^jA^{i-j} \\
=&\sum_{j=0}^{n}x^j\sum_{i=j}^{n}{i \choose j}a_iA^{i-j} \\
=&\sum_{j=0}^{n}x^j\sum_{i=j}^{n}\frac{i!}{j!(i-j)!}a_iA^{i-j} \\
&b_i=\sum_{j=i}^{n}\frac{j!}{i!(j-i)!}a_jA^{j-i} \\
&i! \cdot A^i \cdot b_i=\sum_{j=i}^{n}\frac{j!}{(j-i)!}a_jA^{j} \\
& p_i=\sum_{j=i}^{n}q_jw_{j-i} \\
& p_i=\sum_{j=0}^{n-i}q_{j+i}w_j \\
& p'_i=p_{n-i} \\
& p'_{n-i}=\sum_{j=0}^{n-i}q_{j+i}w_j \\
& p'_i=\sum_{j=0}^{i}q_{j+n-i}w_j \\
& q'_{i}=q_{n-i},q_{j+n-i}=q'_{i-j} \\
& p'_i=\sum_{j=0}^{i}q'_{i-j}w_j
\end{aligned}
$$
只需要对$q',w$求一次卷积即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int mod = 998244353; 5 const int N = 2e6; 6 ll pw(ll a, ll b) { 7 ll res = 1; 8 while(b) { 9 if(b & 1) { 10 res = res * a % mod; 11 } 12 a = a * a % mod; 13 b >>= 1; 14 } 15 return res; 16 } 17 ll fac[N], invfac[N]; 18 ll a[N], q[N], q_[N], w[N], b[N]; 19 ll p_[N], p[N]; 20 ll A, pwA[N], invpwA[N]; 21 int n; 22 23 namespace NTT { 24 const int mod = 998244353, g[2] = { 3, (mod + 1) / 3 }; 25 ll a[N], b[N], f[N]; 26 int n, m; 27 int rev(int x, int n) { 28 int r = 0; 29 for(int i = 0 ; (1 << i) < n ; ++ i) { 30 r = (r << 1) | ((x >> i) & 1); 31 } 32 return r; 33 } 34 void ntt(ll *a, int ty, int n) { 35 for(int i = 0 ; i < n ; ++ i) { 36 f[rev(i, n)] = a[i]; 37 } 38 for(int i = 2 ; i <= n ; i <<= 1) { 39 ll wn = pw(g[ty], (mod - 1) / i); 40 for(int j = 0 ; j < n ; j += i) { 41 ll w = 1; 42 for(int k = j ; k < j + i / 2 ; ++ k) { 43 ll u = f[k], v = f[k + i / 2] * w % mod; 44 f[k] = (u + v) % mod; 45 f[k + i / 2] = (u - v) % mod; 46 w = w * wn % mod; 47 } 48 } 49 } 50 for(int i = 0, inv = pw(n, mod - 2) ; i < n ; ++ i) { 51 a[i] = f[i]; 52 if(ty) { 53 a[i] = a[i] * inv % mod; 54 } 55 } 56 } 57 void ntt() { 58 int len = 1; 59 while(len <= 2 * (n + m)) len <<= 1; 60 ntt(a, 0, len), ntt(b, 0, len); 61 for(int i = 0 ; i < len ; ++ i) { 62 a[i] = a[i] * b[i] % mod; 63 } 64 ntt(a, 1, len); 65 } 66 }; 67 68 int main() { 69 scanf("%d", &n); 70 for(int i = 0 ; i <= n ; ++ i) { 71 scanf("%lld", &a[i]); 72 } 73 scanf("%lld", &A); 74 75 if(A == 0) { 76 for(int i = 0 ; i <= n ; ++ i) { 77 printf("%lld ", a[i]); 78 } 79 return 0; 80 } 81 82 pwA[0] = 1; 83 for(int i = 1 ; i <= n ; ++ i) { 84 pwA[i] = pwA[i - 1] * A % mod; 85 } 86 invpwA[n] = pw(pwA[n], mod - 2); 87 for(int i = n - 1 ; i >= 0 ; -- i) { 88 invpwA[i] = invpwA[i + 1] * A % mod; 89 } 90 fac[0] = 1; 91 for(int i = 1 ; i <= n ; ++ i) { 92 fac[i] = fac[i - 1] * i % mod; 93 } 94 invfac[n] = pw(fac[n], mod - 2); 95 for(int i = n - 1 ; i >= 0 ; -- i) { 96 invfac[i] = invfac[i + 1] * (i + 1) % mod; 97 } 98 for(int i = 0 ; i <= n ; ++ i) { 99 w[i] = invfac[i]; 100 } 101 for(int i = 0 ; i <= n ; ++ i) { 102 q[i] = fac[i] * a[i] % mod * pw(A, i) % mod; 103 q_[n - i] = q[i]; 104 } 105 106 NTT :: n = NTT :: m = n; 107 for(int i = 0 ; i <= n ; ++ i) { 108 NTT :: a[i] = q_[i]; 109 NTT :: b[i] = w[i]; 110 } 111 NTT :: ntt(); 112 for(int i = 0 ; i <= n ; ++ i) { 113 p[i] = NTT :: a[n - i]; 114 } 115 for(int i = 0 ; i <= n ; ++ i) { 116 b[i] = p[i] * invfac[i] % mod * pw(pw(A, i), mod - 2) % mod; 117 } 118 119 for(int i = 0 ; i <= n ; ++ i) { 120 printf("%lld ", (b[i] + mod) % mod); 121 } 122 }View Code
标签:const,int,多项式,sum,3314,res,ECNU,ll,mod 来源: https://www.cnblogs.com/nekko/p/15378279.html