HDU6061 RXD and functions【NTT】

(RXD and functions)

Problem Description
RXD has a polynomial function (f(x)), (f(x)=sum ^{n}_{i=0}c_ix_i)
RXD has a transformation of function (Tr(f,a)), it returns another function g, which has a property that (g(x)=f(x−a)).
Given (a_1,a_2,a_3,…,a_m), RXD generates a polynomial function sequence (g_i), in which (g_0=f) and (g_i=Tr(g_{i−1},a_i))
RXD wants you to find (g_m), in the form of (sum ^{m}_{i=0}b_ix_i)
You need to output bi module (998244353.)
(n≤10^5)

Input
There are several test cases, please keep reading until EOF.
For each test case, the first line consists of (1) integer (n), which means (deg F).
The next line consists of (n+1) intergers (c_i)(0 le ci<998244353), which means the coefficient of the polynomial.
The next line contains an integer (m), which means the length of (a).
The next line contains (m) integers, the (i) - th integer is (a_i).
There are (11) test cases.
(0le ai<998244353)
(sum mle10^5)

Output
For each test case, output an polynomial with degree n, which means the answer.

Sample Input
2
0 0 1
1
1

Sample Output
1 998244351 1
Hint
((x - 1) ^ 2 = x^2 - 2x + 1)

题解:
显然最终操作完的式子为(sum_{i=0}^{n}c_i(x-sum_{i-1}^{m}a_i)^i)
现在我们记((-sum_{i=1}^{m}a_i)\%MOD=a)
然后变成这样:
(sum_{i=0}^{n}c_i(x-a)^i)
接下来我们对式子进行二项式展开:
(sum_{i=0}^{n}sum_{j=i}^{n}C(j,j-i)c_jcdot a^{j-i}cdot x^i)
(j=j-i)替换(j)
(sum_{i=0}^{n}sum_{j=0}^{n-i}C(j+i,j)cdot c_{j+i}cdot a^jcdot x^j)
把组合数展开:
(sum_{i=0}^{n}sum_{j=0}^{n-i}frac{(i+j)!}{i!cdot j!}c_{i+j}cdot a^jcdot x^j)
整理一下,把和内层求和无关的提到外面来得到:
(sum_{i=0}^{n}frac{x^i}{i!}sum_{j=0}^{n-i}c_{i+j}cdot (i+j)!cdotfrac{a^j}{j!})
现在我们先怎么转化里面的式子,使之变成卷积的形式:
(sum_{j=0}^{n-i}c_{i+j}cdot (i+j)!cdotfrac{a^j}{j!})
(j+k=n-i)来做替换:
(Rightarrow sum_{j+k=n-i} c_{n-k}cdot (n-k)!cdot frac{a^j}{j!})
发现这个式子就是卷积的形式了
(A[n]=sum c_{n-i}cdot (n-i)!)
(B[n]=sum frac{a^i}{i!})

(NTT)来搞即可

//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e6+7;
using LL = int_fast64_t;
const LL MOD = 998244353;
const LL g = 3;
int n,limit,m,l,r[MAXN];
LL fact[MAXN],rfact[MAXN],c[MAXN],A[MAXN],B[MAXN];
LL qpow(LL a, LL b){
    LL ret = 1;
    while(b){
        if(b&1) ret = ret * a % MOD;
        b >>= 1;
        a = a * a % MOD;
    }
    return ret;
}
LL inv(LL x){ return qpow(x,MOD-2); }
void NTT(LL arr[], int rev){
    for(int i = 0; i < limit; i++) if(i<r[i]) swap(arr[i],arr[r[i]]);
    for(int len = 1; len < limit; len <<= 1){
        LL wn = qpow(g,(MOD-1)/(len<<1));
        if(rev==-1) wn = inv(wn);
        for(int R = 0; R < limit; R += (len<<1)){
            LL w = 1;
            for(int i = R; i < R + len; i++){
                LL x = arr[i];
                LL y = w * arr[i+len] % MOD;
                arr[i] = (x+y)%MOD;
                arr[i+len] = (x-y+MOD)%MOD;
                w = w * wn % MOD;
            }
        } 
    }
}
void solve(){
    LL a = 0;
    for(int i = 0; i <= n; i++) scanf("%I64d",&c[i]);
    scanf("%d",&m);
    for(int i = 1; i <= m; i++){
        int x; scanf("%d",&x);
        a -= x;
        if(a<0) a += MOD;
    }
    limit = 1, l = 0;
    while(limit<=(n<<1)) limit <<= 1, l++;
    for(int i = 0; i < limit; i++) r[i] = ((r[i>>1]>>1) | ((i&1)<<(l-1)));
    LL powa = 1;
    for(int i = 0; i < limit; i++){
        if(i<=n){
            A[i] = fact[n-i] * c[n-i] % MOD;
            B[i] = powa * rfact[i] %MOD;
            powa = powa * a % MOD;
        }
        else A[i] = B[i] = 0;
    }
    NTT(A,1); NTT(B,1);
    for(int i = 0; i < limit; i++) A[i] = A[i] * B[i] % MOD;
    NTT(A,-1);
    for(int i = 0; i < limit; i++) A[i] = A[i] * inv(limit) % MOD;
    for(int i = 0; i <= n; i++) printf("%I64d ",A[n-i]*rfact[i]%MOD); puts("");
}
int main(){
    fact[0] = 1; for(int i = 1; i < MAXN; i++) fact[i] = i * fact[i-1] % MOD;
    rfact[MAXN-1] = inv(fact[MAXN-1]);
    for(int i = MAXN - 2; i >= 0; i--) rfact[i] = rfact[i+1] * (i+1) % MOD;
    while(scanf("%d",&n)!=EOF) solve();
    return 0;
}
原文地址:https://www.cnblogs.com/kikokiko/p/12599137.html