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,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);
//    for(int i=0;i<len;++i) printf("%lld ",g[i]);
//    printf("
");
    ntt(c,len,1);
//    for(int i=0;i<len;++i) printf("%lld ",c[i]);
//    printf("
");
    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,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("
");
    get_inv(n);
//    for(int i=0;i<n;++i) printf("%lld ",g[i]);
//    printf("
");
    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]); 
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/14087444.html