洛谷3711:倉鼠的數學題(NTT+伯努利數)
阿新 • • 發佈:2019-02-17
題面
題意:給出a陣列,求
所表示多項式的每一項係數。
額,直接將伯努利數帶進S裡,得
設c=k+1-g,則
就是個卷積了。
到處膜拜大佬們的程式,總算把我程式搞對了
但有兩個似乎很重要的問題還不懂。
①樣例是客觀存在的,我推的公式也和題解一樣
為什麼
②
#include <iostream>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
#define mmst(a, b) memset(a, b, sizeof(a))
#define mmcp(a, b) memcpy(a, b, sizeof(b))
typedef long long LL;
const int N=1001000;
const LL mo=998244353 ;
LL I[N],jc[N],Ijc[N];
LL E[N],D[N],B[N],F[N];
int n,rev[N];
LL cheng(LL a,LL b)
{
LL res=1;
for(;b;b>>=1,a=a*a%mo)
if(b&1)
res=res*a%mo;
return res;
}
void init(int lim)
{
int k=-1;
n=1;
while(n<lim)
n<<=1,k++;
for(int i=0;i<n;i++)
rev[i]=(rev[i>>1 ]>>1) | ((i&1)<<k);
}
void ntt(LL *a,int ops)
{
for(int i=0;i<n;i++)
if(i<rev[i])
swap(a[i],a[rev[i]]);
for(int l=2;l<=n;l<<=1)
{
int m=l>>1;
LL wn=(ops) ? cheng(3,(mo-1)/l) : cheng(3,mo-1-(mo-1)/l);
for(int i=0;i<n;i+=l)
{
LL w=1;
for(int k=0;k<m;k++)
{
LL t=a[i+k+m]*w%mo;
a[i+k+m]=(a[i+k]-t+mo)%mo;
a[i+k]=(a[i+k]+t)%mo;
w=w*wn%mo;
}
}
}
if(!ops)
for(int i=0;i<n;i++)
a[i]=a[i]*I[n]%mo;
}
void ny(int x)
{
if(x==1)
return;
ny(x/2);
for(int i=0;i<x;i++)
E[i]=B[i];
init(x*2);
ntt(E,1);
ntt(D,1);
for(int i=0;i<n;i++)
D[i]=D[i]*(2-E[i]*D[i]%mo+mo)%mo;
ntt(D,0);
for(int i=0;i<n;i++)
E[i]=0;
for(int i=x;i<n;i++)
D[i]=0;
}
LL nn,aa[N];
int main()
{
I[1]=Ijc[0]=jc[0]=1;
for(int i=2;i<N;i++)
I[i]=I[mo%i]*(mo-mo/i)%mo;
for(int i=1;i<N;i++)
jc[i]=jc[i-1]*i%mo,Ijc[i]=Ijc[i-1]*I[i]%mo;
cin>>nn;
for(int i=0;i<=nn;i++)
scanf("%lld",&aa[i]),aa[i]=aa[i]*jc[i]%mo;
printf("%lld ",aa[0]);
for(int i=0;i<=nn+1;i++)
B[i]=Ijc[i+1];
init(nn+1);
D[0]=1;
ny(n);
for(int i=nn+1;i<N;i++)
D[i]=0;
D[1]=499122177;
mmcp(F,D);
mmst(D,0);
for(int i=0;i<=nn;i++)
D[nn+1-i]=F[i];
init(nn+nn+3);
ntt(D,1);
ntt(aa,1);
for(int i=0;i<n;i++)
D[i]=D[i]*aa[i]%mo;
ntt(D,0);
for(int i=1;i<=nn+1;i++)
printf("%lld ",D[i+nn]*Ijc[i]%mo);
cout<<endl;
return 0;
}