1. 程式人生 > 實用技巧 >P4725 【模板】多項式對數函式(多項式 ln)

P4725 【模板】多項式對數函式(多項式 ln)

https://www.luogu.com.cn/problem/P4725

ln的導數=原多項式的導數/求逆

再積分得到多項式除去常數項的的ln

即得到的是B'(x)=a0+a1*x+a2*x^2+……

所以B(x)=C+a0*x+a1/2*x^2+a2/3*x^3……

還需要帶入求C

這道題給出了a0=1

當n=1時,ln(A(x))=ln(1)=0,所以C=0

所以多項式求ln的意義是什麼QWQ

#include<cstdio>
#include<algorithm>

using namespace std;

#define N 300001

const int mod=998244353
; const int G=3; long long a[N],f[N],g[N],c[N],ln[N]; int rev[N]; long long poww(long long p,long long q) { long long s=1; for(;q;p=p*p%mod,q>>=1) if(q&1) s=s*p%mod; return s; } void get_der(int n) { for(int i=1;i<n;++i) f[i-1]=a[i]*i%mod; } void ntt(long long
*b,int n,int tag) { for(int i=0;i<n;++i) if(i<rev[i]) swap(b[i],b[rev[i]]); for(int i=1;i<n;i<<=1) { long long wn=poww(G,(mod-1)/(i*2)); if(tag<0) wn=poww(wn,mod-2); for(int j=0,p=i<<1;j<n;j+=p) { long long w=1;
for(int k=0;k<i;++k,w=w*wn%mod) { long long x=b[j+k],y=b[j+k+i]*w%mod; b[j+k]=(x+y)%mod; b[j+k+i]=(x-y+mod)%mod; } } } if(tag<0) { long long inv=poww(n,mod-2); for(int i=0;i<n;++i) b[i]=b[i]*inv%mod; } } void get_inv(int n) { if(n==1) { g[0]=poww(a[0],mod-2); // printf("%d : %lld\n",n,g[0]); return; } get_inv(n+1>>1); int len=1,m=0,nn=2*n-1; for(;len<nn;len<<=1,++m); for(int i=1;i<len;++i) rev[i]=rev[i>>1]>>1|((i&1)<<m-1); for(int i=0;i<n;++i) c[i]=a[i]; for(int i=n;i<len;++i) c[i]=0; ntt(g,len,1); // printf("%d\n",n); // for(int i=0;i<len;++i) printf("%lld ",g[i]); // printf("\n"); ntt(c,len,1); // for(int i=0;i<len;++i) printf("%lld ",c[i]); // printf("\n"); for(int i=0;i<len;++i) g[i]=(2-c[i]*g[i]%mod+mod)%mod*g[i]%mod; // for(int i=0;i<n;++i) printf("%d : %lld\n",n,g[i]); ntt(g,len,-1); for(int i=n;i<len;++i) g[i]=0; } void get_inte(int n) { for(int i=1;i<n;++i) ln[i]=f[i-1]*poww(i,mod-2)%mod; ln[0]=0; } void solve(int n) { get_der(n); // for(int i=0;i<n;++i) printf("%lld ",f[i]); // printf("\n"); get_inv(n); // for(int i=0;i<n;++i) printf("%lld ",g[i]); // printf("\n"); int len=1,m=0,nn=2*n-1; for(;len<nn;len<<=1,++m); for(int i=0;i<len;++i) rev[i]=rev[i>>1]>>1|((i&1)<<m-1); ntt(f,len,1); ntt(g,len,1); for(int i=0;i<len;++i) f[i]=f[i]*g[i]%mod; ntt(f,len,-1); get_inte(n); } int main() { int n; scanf("%d",&n); for(int i=0;i<n;++i) scanf("%d",&a[i]); solve(n); for(int i=0;i<n;++i) printf("%lld ",ln[i]); }