题解 P4725 【【模板】多项式对数函数】

xzyxzy

2018-07-05 20:32:58

Solution

~~我不知道大家为什么要写这么长~~,当然也不知道为什么大家的这么快 原理就是对两边同时求导 $$G(x)=F(A(x)),F(x)=ln(x)$$ $$G'(x)=F'(A(x))A'(x)=\frac{A'(x)}{A(x)}$$ 所以对A求导求个逆就算出了G 然后由于求导和不定积分是互逆的,所以对G求个不定积分就好了 补充一下: **求导公式**$$x^{a'}=ax^{a-1}$$ **积分公式**$$\int x^adx=\frac{1}{a+1}x^{a+1}$$ 详情请见代码中两个函数*Dao()/Jifen()* ```cpp #include<iostream> #include<cstdio> using namespace std; const int N=400100; const int mod=998244353; int n,m,A[N],B[N],C[N],D[N],F[N],G[N],r[N],l,tt; int ksm(int a,int k) { int s=1;for(;k;k>>=1,a=1ll*a*a%mod) if(k&1) s=1ll*s*a%mod; return s; } void Getl(int len) { for(l=1,tt=0;l<=len;l<<=1) tt++;tt--; for(int i=0;i<l;i++) r[i]=(r[i>>1]>>1)|((i&1)<<tt); } void NTT(int *P,int op) { for(int i=0;i<l;i++) if(i<r[i]) swap(P[i],P[r[i]]); for(int i=1;i<l;i<<=1) { int W=ksm(3,(mod-1)/(i<<1)); if(op<0) W=ksm(W,mod-2); for(int j=0,p=i<<1;j<l;j+=p) for(int k=0,w=1;k<i;k++,w=1ll*w*W%mod) { int X=P[j+k],Y=1ll*P[j+k+i]*w%mod; P[j+k]=(X+Y)%mod;P[j+k+i]=((X-Y)%mod+mod)%mod; } } if(op<0) for(int i=0,u=ksm(l,mod-2);i<l;i++) P[i]=1ll*P[i]*u%mod; } void GetInv(int *f,int *g,int n) { if(n==1) {g[0]=ksm(f[0],mod-2);return;} GetInv(f,g,n>>1); Getl(n); for(int i=0;i<n;i++) C[i]=f[i],D[i]=g[i]; for(int i=n;i<l;i++) C[i]=D[i]=0; NTT(C,1);NTT(D,1); for(int i=0;i<l;i++) C[i]=1ll*C[i]*D[i]%mod*D[i]%mod; NTT(C,-1); for(int i=0;i<n;i++) g[i]=((2ll*g[i]%mod-C[i])%mod+mod)%mod; } void Dao(int *A,int *B,int len) { for(int i=1;i<len;i++) B[i-1]=1ll*i*A[i]%mod;B[len-1]=0; } void Jifen(int *A,int *B,int len) { for(int i=1;i<len;i++) B[i]=1ll*A[i-1]*ksm(i,mod-2)%mod;B[0]=0; } void Getln(int *f,int *g,int n) { Dao(f,A,n); GetInv(f,B,n); Getl(n); NTT(A,1);NTT(B,1); for(int i=0;i<l;i++) A[i]=1ll*A[i]*B[i]%mod; NTT(A,-1); Jifen(A,g,n); } int main() { scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&F[i]); for(m=1;m<=n;m<<=1); Getln(F,G,m); for(int i=0;i<n;i++) printf("%d ",G[i]); } ``` ~~广告:[博主有多项式算法题单哦](https://www.cnblogs.com/xzyxzy/)~~