公式推导参考自http://blog.csdn.net/ZLH_HHHH/article/details/76576544?locationNum=1&fps=1
题意:相当于求的每项系数
思路:
这样就可以用NTT优化来计算
代码:
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
const double PI = acos(-1.0);
typedef long long LL;
const LL MAXN = 400005;
const LL P = 998244353;
const LL G = 3;
const LL NUM = 20;
LL wn[NUM];
LL Pow(LL a,LL b,LL m)
{
LL ans=1;
a%=m;
while(b)
{
if(b&1) ans=ans*a%m;
b>>=1;
a=a*a%m;
}
return ans;
}
void GetWn()
{
for(int i=0;i<NUM;i++)
{
LL t=1LL << i;
wn[i]=Pow(G,(P-1)/t,P);
}
}
void change(LL *y, LL len)
{
LL i,j,k;
for (i=1,j=len/2;i<len-1;i++)
{
if (i<j) swap(y[i],y[j]);
k=len/2;
while (j>=k)
{
j-=k;
k/=2;
}
if (j<k) j+=k;
}
}
void ntt(LL *y, LL len, LL on)
{
change(y,len);
LL id=0;
for (LL h=2;h<=len;h<<=1)
{
id++;
for (LL j=0; j<len; j+=h)
{
LL w=1;
for (LL k=j; k<j+h/2;k++)
{
LL u =y[k]%P;
LL t =w*y[k+h/2]%P;
y[k]=(u+t)%P;
y[k+h/2]=(u-t+P)%P;
w=w*wn[id]%P;
}
}
}
if(on==-1)
{
for(LL i=1;i<len/2;i++)
swap(y[i],y[len-i]);
LL Inv=Pow(len,P-2,P);
for(LL i=0;i<len;i++)
y[i]=y[i]*Inv%P;
}
}
LL fac[MAXN];
LL inv[MAXN];
LL c[MAXN];
LL b[MAXN];
LL data[MAXN];
int main()
{
GetWn();
fac[0]=1;
for(int i=1;i<MAXN;i++)
fac[i]=fac[i-1]*i*1LL%P;///计算阶乘
inv[MAXN-1]=Pow(fac[MAXN-1],P-2,P);
for(int i=MAXN-2;i>=0;i--)
inv[i]=inv[i+1]*(i+1)*1LL%P;///计算阶乘的逆元
int n;
while(scanf("%d",&n)!=-1)
{
n++;
for(int i=0;i<n;i++)
scanf("%lld",&data[i]);
for(int i=0;i<n;i++)
b[i]=data[n-1-i]*fac[n-1-i]%P;
int m;
scanf("%d",&m);
LL S=0;
for(int i=0;i<m;i++)
{
LL a;
scanf("%lld",&a);
S=S+a;
if(S>=P) S-=P;
}
for(int i=0;i<n;i++)
{
c[i]=Pow((P-S),i,P);
c[i]=c[i]*inv[i]%P;
}
LL len=1;
while(len<2LL*n)
len<<=1LL;
for(int i=n;i<len;i++) c[i]=b[i]=0;
ntt(b,len,1), ntt(c,len,1);
for(int i=0;i<len;i++)
c[i]=c[i]*b[i]%P;
ntt(c,len,-1);
for(int i=0;i<n;i++)
{
LL ans=c[n-1-i]*inv[i]%P;
printf("%lld ",ans);
}
printf("\n");
}
return 0;
}