多项式求
ln
\ln
ln
(
ln
A
(
x
)
)
′
=
A
′
(
x
)
A
(
x
)
(\ln A(x))'=\frac{A'(x)}{A(x)}
(lnA(x))′=A(x)A′(x)
算出等式右边后再积回来就行。
多项式求
e
x
p
exp
exp
定义函数
F
(
G
(
x
)
)
=
ln
G
(
x
)
−
A
(
x
)
F(G(x))=\ln G(x)-A(x)
F(G(x))=lnG(x)−A(x)
要求
F
(
G
(
x
)
)
F(G(x))
F(G(x))的零点,用牛顿迭代解方程。
G
(
x
)
=
G
0
(
x
)
−
F
(
G
0
(
x
)
)
F
′
(
G
0
(
x
)
)
G(x)=G_0(x)-\frac{F(G_0(x))}{F'(G_0(x))}
G(x)=G0(x)−F′(G0(x))F(G0(x))
F
(
G
0
(
x
)
)
=
ln
G
0
(
x
)
−
A
(
x
)
F(G_0(x))=\ln G_0(x)-A(x)
F(G0(x))=lnG0(x)−A(x)
F
′
(
G
0
(
x
)
)
=
1
G
0
(
x
)
F'(G_0(x))=\frac{1}{G_0(x)}
F′(G0(x))=G0(x)1
G
(
x
)
=
G
0
(
x
)
(
1
−
ln
G
0
(
x
)
+
A
(
x
)
)
G(x)=G_0(x)(1-\ln G_0(x)+A(x))
G(x)=G0(x)(1−lnG0(x)+A(x))
求
A
(
x
)
B
A(x)^B
A(x)B
若
A
(
x
)
A(x)
A(x)常数项为
1
1
1,则直接
ln
\ln
ln然后
exp
\exp
exp回来。
否则设
A
(
x
)
A(x)
A(x)最低项为
a
x
b
ax^b
axb,先把
A
A
A除以
a
x
b
ax^b
axb,像上面那样做,最后乘回来就行。注意次数
m
o
d
p
mod\ p
mod p和
m
o
d
φ
(
p
)
mod\ \varphi(p)
mod φ(p)的问题,另外判多项式全
0
0
0要注意一下次数不取模。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
const int N=270005,mod=998244353,inv2=(mod+1)>>1;
int n,m,k,len,p,a[N],rev[N],inv[N],w[20][N],iw[20][N];
long long mx;
inline int add(int a,int b){
a+=b;
return a<mod?a:a-mod;
}
inline int dec(int a,int b){
a-=b;
return a<0?a+mod:a;
}
inline int mul(int a,int b){
return 1LL*a*b%mod;
}
inline int fastpow(int a,int x){
int res=1;
while(x){
if(x&1){
res=mul(res,a);
}
x>>=1;
a=mul(a,a);
}
return res;
}
int rd(){
char ch=getchar();
int res=0;
while(ch<'0'||ch>'9'){
ch=getchar();
}
while(ch>='0'&&ch<='9'){
mx=max(mx,1LL*res*10+ch-'0');
res=add(mul(res,10),ch-'0');
p=(1LL*p*10+ch-'0')%(mod-1);
ch=getchar();
}
return res;
}
void init(int len){
inv[1]=1;
for(int i=2;i<=len;i++){
inv[i]=mul(inv[mod%i],dec(mod,mod/i));
}
for(int i=1,t=0;i<len;i<<=1,t++){
int wn=fastpow(3,(mod-1)/i/2),iwn=fastpow(wn,mod-2);
for(int j=0;j<len;j+=(i<<1)){
int w=1,iw=1;
for(int k=j;k<j+i;k++,w=mul(w,wn),iw=mul(iw,iwn)){
::w[t][k]=w;
::iw[t][k]=iw;
}
}
}
}
void ntt(int a[],int len){
for(int i=0;i<len;i++){
rev[i]=(rev[i>>1]>>1)|((i&1)*(len>>1));
if(i<rev[i]){
swap(a[i],a[rev[i]]);
}
}
for(int i=1,t=0;i<len;i<<=1,t++){
for(int j=0;j<len;j+=(i<<1)){
int x,y;
for(int k=j;k<j+i;k++){
x=a[k];
y=mul(w[t][k],a[k+i]);
a[k]=add(x,y);
a[k+i]=dec(x,y);
}
}
}
}
void intt(int a[],int len){
for(int i=0;i<len;i++){
rev[i]=(rev[i>>1]>>1)|((i&1)*(len>>1));
if(i<rev[i]){
swap(a[i],a[rev[i]]);
}
}
for(int i=1,t=0;i<len;i<<=1,t++){
for(int j=0;j<len;j+=(i<<1)){
int x,y;
for(int k=j;k<j+i;k++){
x=a[k];
y=mul(iw[t][k],a[k+i]);
a[k]=add(x,y);
a[k+i]=dec(x,y);
}
}
}
for(int i=0;i<len;i++){
a[i]=mul(a[i],inv[len]);
}
}
void getinv(int a[],int res[],int len){
static int b[N],c[N],d[N];
for(int i=0;i<(len<<1);i++){
b[i]=c[i]=d[i]=0;
}
b[0]=fastpow(a[0],mod-2);
for(int i=2;i<=len;i<<=1){
for(int j=0;j<i;j++){
c[j]=b[j];
d[j]=a[j];
}
ntt(c,i<<1);
ntt(d,i<<1);
for(int j=0;j<(i<<1);j++){
c[j]=mul(c[j],dec(2,mul(c[j],d[j])));
}
intt(c,i<<1);
for(int j=0;j<i;j++){
b[j]=c[j];
}
}
for(int i=0;i<len;i++){
res[i]=b[i];
}
}
int bsgs(int a,int b){
static map<int,int> mp;
mp.clear();
int p=ceil(sqrt(mod)),s=1;
for(int i=0;i<p;i++,s=mul(s,a)){
mp[s]=i;
}
s=fastpow(s,mod-2);
for(int i=0,j=b;i<mod;i+=p,j=mul(j,s)){
if(mp.count(j)){
return i+mp[j];
}
}
return 0;
}
void getsqrt(int a[],int res[],int len){
static int b[N],c[N],d[N];
for(int i=0;i<(len<<1);i++){
b[i]=c[i]=d[i]=0;
}
int tmp=fastpow(3,bsgs(3,a[0])>>1);
tmp=min(tmp,mod-tmp);
b[0]=tmp;
for(int i=2;i<=len;i<<=1){
for(int j=0;j<i;j++){
c[j]=add(b[j],b[j]);
d[j]=a[j];
}
getinv(c,c,i);
ntt(c,i<<1);
ntt(d,i<<1);
for(int j=0;j<(i<<1);j++){
c[j]=mul(c[j],d[j]);
}
intt(c,i<<1);
for(int j=0;j<i;j++){
b[j]=add(mul(b[j],inv2),c[j]);
}
}
for(int i=0;i<len;i++){
res[i]=b[i];
}
}
void derivative(int a[],int res[],int len){
static int b[N];
for(int i=0;i<len-1;i++){
b[i]=mul(i+1,a[i+1]);
}
b[len-1]=0;
for(int i=0;i<len;i++){
res[i]=b[i];
}
}
void integral(int a[],int res[],int len){
static int b[N];
b[0]=0;
for(int i=1;i<len;i++){
b[i]=mul(a[i-1],inv[i]);
}
for(int i=0;i<len;i++){
res[i]=b[i];
}
}
void getln(int a[],int res[],int len){
static int b[N],c[N];
for(int i=0;i<(len<<1);i++){
b[i]=c[i]=i<len?a[i]:0;
}
derivative(b,b,len);
getinv(c,c,len);
ntt(b,len<<1);
ntt(c,len<<1);
for(int i=0;i<(len<<1);i++){
b[i]=mul(b[i],c[i]);
}
intt(b,len<<1);
integral(b,res,len);
}
void getexp(int a[],int res[],int len){
static int b[N],c[N],d[N];
for(int i=0;i<(len<<1);i++){
b[i]=c[i]=d[i]=0;
}
b[0]=1;
for(int i=2;i<=len;i<<=1){
for(int j=0;j<i;j++){
c[j]=d[j]=b[j];
}
getln(c,c,i);
for(int j=0;j<i;j++){
c[j]=dec(a[j]+(j==0),c[j]);
}
ntt(c,i<<1);
ntt(d,i<<1);
for(int j=0;j<(i<<1);j++){
c[j]=mul(c[j],d[j]);
}
intt(c,i<<1);
for(int j=0;j<i;j++){
b[j]=c[j];
}
}
for(int i=0;i<len;i++){
res[i]=b[i];
}
}
int main(){
scanf("%d",&n),k=rd();
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
while(m<n&&!a[m]){
m++;
}
if(m*mx>=n){
for(int i=0;i<n;i++){
printf("0 ");
}
return 0;
}
int tmp=fastpow(a[m],p),inv=fastpow(a[m],mod-2);
for(int i=0;i<n;i++){
a[i]=i<n-m?mul(a[i+m],inv):0;
}
for(len=1;len<n;len<<=1);
init(len<<1);
getln(a,a,len);
for(int i=0;i<len;i++){
a[i]=mul(a[i],k);
}
getexp(a,a,len);
for(int i=0;i<n;i++){
if(i<m*k){
printf("0 ");
}else{
printf("%d ",mul(a[i-m*k],tmp));
}
}
return 0;
}