已知 f ( x ) f(x) f(x),求 g ( x ) = f ( x ) k ( m o d x n ) g(x) = f(x)^k\pmod{x^n} g(x)=f(x)k(modxn)
版本
1
:
1:
1:
q
k
≤
1
e
6
qk\leq1e6
qk≤1e6,其中
q
q
q是
f
(
x
)
f(x)
f(x)的最高次数。
将
f
(
x
)
f(x)
f(x)
F
F
T
FFT
FFT后直接对每个点值求
k
k
k次方后再
I
D
F
T
IDFT
IDFT回去即可。
非常快,不要小看了这种做法。脑筋急转弯
O
(
n
log
n
)
O(n\log n)
O(nlogn)
版本
2
:
2:
2:
k
≤
1
e
9
k\leq 1e9
k≤1e9
倍增求快速幂。
注意和上一个版本的区别。
F
F
T
FFT
FFT后的操作是一定要注意防止循环卷积出现的,因为这不是我们所希望的。
所以每层都要
I
D
F
T
IDFT
IDFT然后
(
m
o
d
x
n
)
\pmod{x^n}
(modxn)再
F
F
T
FFT
FFT
(也就是说不要把
(
m
o
d
x
n
)
\pmod{x^n}
(modxn)看做不存在,我们有两个模数,一个是
x
n
x^n
xn,一个是
998244353
998244353
998244353)
O
(
n
log
n
log
k
)
O(n\log n\log k)
O(nlognlogk)
版本
3
:
3:
3:
k
≤
1
e
1
e
50
k\leq 1e1e50
k≤1e1e50,保证
f
(
x
)
[
0
]
=
1
f(x)[0]=1
f(x)[0]=1对你没有看错
我们考虑
f
(
x
)
k
=
exp
(
k
ln
f
(
x
)
)
f(x)^k=\exp(k\ln f(x))
f(x)k=exp(klnf(x))
发现在
(
m
o
d
998244353
)
\pmod {998244353}
(mod998244353)的意义下.
k
ln
f
(
x
)
≡
(
k
m
o
d
998244353
)
f
(
x
)
(
m
o
d
998244353
)
k\ln f(x) \equiv (k\mod 998244353) f(x) \pmod {998244353}
klnf(x)≡(kmod998244353)f(x)(mod998244353)
所以我们可以在读入时把
k
m
o
d
998244353
k\mod 998244353
kmod998244353
然后我们既可以用
exp
\exp
exp
也可以用版本
2
2
2的方法。
注意因为我们要求
ln
f
(
x
)
[
0
]
(
m
o
d
998244353
)
\ln f(x)[0] \pmod {998244353}
lnf(x)[0](mod998244353)
所以我们需要
f
(
x
)
[
0
]
=
1
,
ln
f
(
x
)
[
0
]
=
0
f(x)[0]=1 , \ln f(x)[0] = 0
f(x)[0]=1,lnf(x)[0]=0
不然,我实在不知道自然对数模一个素数的值是多少。
版本
4
:
4:
4:
k
≤
1
e
1
e
50
k\leq 1e1e50
k≤1e1e50,不保证
f
(
x
)
[
0
]
=
1
f(x)[0]=1
f(x)[0]=1
考虑我们求
exp
\exp
exp的过程,是用牛顿迭代。
那么我们需要一个初值
x
x
x,
这个初值应该满足
x
=
exp
k
ln
f
(
x
)
[
0
]
=
f
(
x
)
[
0
]
k
x = \exp{k\ln f(x)[0]} = f(x)[0]^k
x=expklnf(x)[0]=f(x)[0]k
所以我们只需要在求
exp
\exp
exp的时候将初值设定为这个即可。
不用管
ln
\ln
ln后的第
0
0
0项是多少,它再
exp
\exp
exp后的第
0
0
0项就是这个值。
但是
ln
0
\ln 0
ln0是没有定义的,
所以
f
(
x
)
[
0
]
=
0
f(x)[0]=0
f(x)[0]=0时我们需要平移多项式。
A C C o d e \mathrm {AC \ Code} AC Code
#include<bits/stdc++.h>
#define maxn 300005
#define rep(i,j,k) for(int i=(j);i<=(k);i++)
#define per(i,j,k) for(int i=(j);i>=(k);i--)
#define mod 998244353
using namespace std;
int Wl,W[maxn],lg[maxn],r[maxn],inv[maxn];
int Pow(int b,int k){ int r=1;for(;k;k>>=1,b=1ll*b*b%mod) if(k&1) r=1ll*r*b%mod;return r; }
struct cp{int a,b;cp(int a=0,int b=0):a(a),b(b){}};
cp mul(cp a,cp b,int w){ return cp((1ll*a.a*b.a+1ll*w*a.b%mod*b.b)%mod,(1ll*a.a*b.b+1ll*a.b*b.a)%mod); }
cp Pow(cp b,int k,int w){ cp r(1,0);for(;k;k>>=1,b=mul(b,b,w)) if(k&1) r=mul(r,b,w);return r; }
int SQRT(int n){
if(Pow(n,(mod-1)/2)==mod-1) return -1;
for(int a,w;a=rand(),1;) if(Pow((w=(1ll*a*a-n)%mod+mod)%mod,(mod-1)/2)==mod-1)
return Pow(cp(a,1),(mod+1)/2,w).a;
}
void init(int n){
for(W[0]=inv[0]=inv[1]=Wl=1;n>=2*Wl;Wl<<=1);int pw=Pow(3,(mod-1)/Wl/2);
rep(i,1,Wl<<1) W[i]=1ll*W[i-1]*pw%mod,(i>1)&&(lg[i]=lg[i>>1]+1,inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod);
}
void FFT(int *A,int n,int tp){
rep(i,1,n-1) (i<(r[i]=(r[i>>1]>>1)|((i&1)<<(lg[n]-1))))&&(swap(A[i],A[r[i]]),0);
for(int L=1,B=Wl;L<n;L<<=1,B>>=1) for(int s=0;s<n;s+=L<<1) for(int k=s,x=0,t;k<s+L;k++,x+=B)
t=1ll*(tp==1?W[x]:W[(Wl<<1)-x])*A[k+L]%mod,A[k+L]=(A[k]-t)%mod,A[k]=(A[k]+t)%mod;
if(tp^1) rep(i,0,n-1) A[i]=1ll*A[i]*inv[n]%mod;
}
void INV(int *A,int *B,int n){
B[B[1]=0]=Pow(A[0],mod-2);static int t[maxn];
for(int k=2,L=4;k<(n<<1);k<<=1,L<<=1){
rep(i,0,L-1) t[i]=i<k?A[i]:B[i]=0;FFT(t,L,1),FFT(B,L,1);
rep(i,0,L-1) B[i]=B[i]*(2-1ll*t[i]*B[i]%mod)%mod;FFT(B,L,-1);
rep(i,min(n,k),L-1) B[i]=0;
}
}
void LN(int *A,int *B,int n){
INV(A,B,n);static int t[maxn];int L=1<<lg[2*n-2]+1;
rep(i,0,L-1) t[i]=i<n-1?A[i+1]*(i+1ll)%mod:0,(i>=n)&&(B[i]=0);FFT(B,L,1),FFT(t,L,1);
rep(i,0,L-1) t[i]=1ll*t[i]*B[i]%mod;FFT(t,L,-1);
rep(i,0,L-1) B[i]=(i&&i<n?1ll*t[i-1]*inv[i]%mod:0);
}
void EXP(int *A,int *B,int n,int b0=1){
B[B[1]=0]=b0;static int t[maxn];
for(int k=2,L=4;k<(n<<1);k<<=1,L<<=1){
LN(B,t,k);rep(i,0,L-1) t[i]=i<k?((i==0)-t[i]+A[i])%mod:B[i]=0;
FFT(t,L,1),FFT(B,L,1);rep(i,0,L-1) B[i]=1ll*B[i]*t[i]%mod;
FFT(B,L,-1);rep(i,min(n,k),L-1) B[i]=0;
}
}
void SQT(int *A,int *B,int n){
B[0]=SQRT(A[0]);if(B[0]>mod-B[0]) B[0] = mod-B[0];
B[1]=0;static int t[maxn],t2[maxn];
for(int k=2,L=4;k<(n<<1);k<<=1,L<<=1){
INV(B,t,k);rep(i,0,L-1) t2[i]=i<k?A[i]:t[i]=0;
FFT(t,L,1),FFT(t2,L,1);rep(i,0,L-1) t[i]=1ll*t[i]*t2[i]%mod;
FFT(t,L,-1);rep(i,0,L-1) B[i]=(i<min(k,n)?(B[i]+t[i])*(mod+1ll)/2%mod:0);
}
}
void INT(int *A,int *B,int n){ rep(i,0,n-1) B[i] = (i ? 1ll * A[i-1] * inv[i] % mod : 0);}
void DER(int *A,int *B,int n){ rep(i,0,n-2) B[i]=A[i+1]*(i+1ll)%mod; }
void POW(int *A,int *B,int n,int k){
static int t[maxn],t2[maxn];
int p=0;for(;p<n && A[p]==0;p++);
if(1ll*p*k>=n-1){
rep(i,0,n-1) B[i]=0;
return;
}
rep(i,p,n) t2[i-p]=A[i];
LN(t2,t,n-p*k);
rep(i,0,n-p*k-1) t[i]=1ll*t[i]*k%mod;
EXP(t,B,n-p*k,Pow(t2[0],k));
per(i,n-1,0) B[i]=i<p*k?0:B[i-p*k];
}
int n,m,k;int A[maxn],B[maxn];
int main(){
scanf("%d",&n);init(2*n);
char ch;
for(;!isdigit(ch=getchar()););
for(k=ch-'0';isdigit(ch=getchar());k=(k*10ll+ch-'0')%mod);
rep(i,0,n-1) scanf("%d",&A[i]);
POW(A,B,n,k);
rep(i,0,n-1) printf("%d%c",(B[i]+mod)%mod," \n"[i==n-1]);
}