其他分享
首页 > 其他分享> > [ECNU] 3314. 多项式展开 (1)

[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