题目链接
题意:
给出 n − 1 n-1 n−1次多项式 A ( x ) A(x) A(x),求一个   m o d     x n \bmod{\:x^n} modxn下的多项式 B ( x ) B(x) B(x),满足 B ( x ) ≡ ln A ( x ) ( m o d x n ) B(x) \equiv \ln A(x)(mod\ x^n) B(x)≡lnA(x)(mod xn)。
在 mod 998244353 \text{mod } 998244353 mod 998244353下进行。
题解:
好吧,我们需要用到一些微积分的知识。先介绍一下对于一个多项式,求导和积分后多项式会变成什么样子。
先介绍一下求导。对于一个多项式 f ( x ) = a 0 + a 1 x + a 2 x 2 + . . . + a n x n f(x)=a_0+a_1x+a_2x^2+...+a_nx^n f(x)=a0+a1x+a2x2+...+anxn,我们对其求导之后就会变成 f ′ ( x ) = a 1 + 2 a 2 x + 3 a 3 x 2 + . . . + n a n x n − 1 f'(x)=a_1+2a_2x+3a_3x^2+...+na_nx^{n-1} f′(x)=a1+2a2x+3a3x2+...+nanxn−1,也就是对于每一项,原来的指数乘到系数上,然后指数减一。
然后介绍一下积分。对于一个多项式 f ( x ) = a 0 + a 1 x + a 2 x 2 + . . . + a n − 1 x n − 1 f(x)=a_0+a_1x+a_2x^2+...+a_{n-1}x^{n-1} f(x)=a0+a1x+a2x2+...+an−1xn−1,我们对其积分之后就会变成 ∫ f ( x ) = a 0 1 x + a 1 2 x 2 + . . . + a n − 1 n x n + c \int f(x)=\frac{a_0}{1}x+\frac{a_1}{2}x^2+...+\frac{a_{n-1}}{n}x^n+c ∫f(x)=1a0x+2a1x2+...+nan−1xn+c,也就是对于第 i i i项,它的系数变为 a i − 1 i \frac{a_{i-1}}{i} iai−1, + c +c +c是加上一个丢失的常数。
我们知道导数和积分可以看作逆运算,即 g ( x ) = ∫ g ′ ( x ) g(x)=\int g'(x) g(x)=∫g′(x)。然后我们还要知道 ln ′ ( x ) = 1 x \ln'(x)=\frac{1}{x} ln′(x)=x1。然后对于一个复合函数 f ( g ( x ) ) f(g(x)) f(g(x)),它的导数 f ( g ( x ) ) ′ f(g(x))' f(g(x))′的求导法则是 f ′ ( g ( x ) ) g ′ ( x ) f'(g(x))g'(x) f′(g(x))g′(x)。
好,我们开始推式子。 ln A ( x ) = ∫ ( ln A ( x ) ) ′ = ∫ ( 1 A ( x ) A ′ ( x ) ) = ∫ A ′ ( x ) A ( x ) \ln A(x)=\int(\ln A(x))'=\int (\frac{1}{A(x)}A'(x))=\int \frac{A'(x)}{A(x)} lnA(x)=∫(lnA(x))′=∫(A(x)1A′(x))=∫A(x)A′(x)
对于一个多项式,我们先求导再积分多项式不变,于是我们先求导,算出 A ′ ( x ) A'(x) A′(x),其中的 1 A ( x ) \frac{1}{A(x)} A(x)1可以用多项式求逆来 O ( n l o g n ) O(nlogn) O(nlogn)的求出来,然后我们再积分回去就好了。其中知道了对多项式的求导和积分法则之后求导和积分都可以 O ( n ) O(n) O(n)完成,于是最后复杂度是 O ( n l o g n ) O(nlogn) O(nlogn)。
代码:
#include
using namespace std;
int n,m,l,rev[400010];
long long a[400010],b[400010],c[400010],d[400010],x[400010],y[400010];
const long long mod=998244353,g=3,gi=332748118;
inline int read()
{
int x=0;
char s=getchar();
while(s>'9'||s<'0')
s=getchar();
while(s>='0'&&s<='9')
{
x=x*10+s-'0';
s=getchar();
}
return x;
}
inline long long ksm(long long x,long long y)
{
long long res=1;
while(y)
{
if(y&1)
res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
inline void ntt(long long *a,int dft,int len)
{
m=len;
l=0;
for(len=1;len<m;len<<=1)
++l;
for(int i=0;i<len;++i)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(l-1));
for(int i=0;i<len;++i)
{
if(i<rev[i])
swap(a[i],a[rev[i]]);
}
for(int i=1;i<len;i<<=1)
{
long long wn=ksm((dft==1?g:gi),(mod-1)/(i<<1));
for(int j=0,p=(i<<1);j<len;j+=p)
{
long long w=1;
for(int k=0;k<i;++k)
{
long long xx=a[j+k],yy=w*a[i+j+k]%mod;
a[j+k]=(xx+yy)%mod;
a[i+j+k]=(xx-yy+mod)%mod;
w=w*wn%mod;
}
}
}
if(dft==-1)
{
long long ni=ksm(m,mod-2);
for(int i=0;i<len;++i)
a[i]=a[i]*ni%mod;
}
}
inline void inv(long long *a,long long *b,int len)
{
if(len==1)
{
b[0]=ksm(a[0],mod-2);
return;
}
inv(a,b,len>>1);
for(int i=0;i<len;++i)
{
x[i]=a[i];
y[i]=b[i];
}
ntt(x,1,len<<1);
ntt(y,1,len<<1);
for(int i=0;i<(len)<<1;++i)
x[i]=x[i]*y[i]%mod*y[i]%mod;
ntt(x,-1,len<<1);
for(int i=0;i<len;++i)
b[i]=(b[i]*2%mod-x[i]+mod)%mod;
for(int i=0;i<(len<<1);++i)
{
x[i]=0;
y[i]=0;
}
}
int main()
{
n=read();
for(int i=0;i<=n-1;++i)
a[i]=read();
int ji;
for(ji=1;ji<=n;ji<<=1);
for(int i=1;i<ji;++i)
b[i-1]=a[i]*i%mod;
b[ji-1]=0;
inv(a,c,ji);
ntt(b,1,ji<<1);
ntt(c,1,ji<<1);
for(int i=0;i<(ji<<1);++i)
b[i]=b[i]*c[i]%mod;
ntt(b,-1,ji<<1);
for(int i=1;i<ji;++i)
c[i]=b[i-1]*ksm(i,mod-2)%mod;
c[0]=0;
for(int i=0;i<n;++i)
printf("%lld ",c[i]);
printf("\n");
return 0;
}