• 【洛谷4725】【模板】多项式对数函数(多项式 ln)


    点此看题面

    大致题意: 给定多项式(F(x)),求(G(x))满足(G(x)equiv ln F(x)(mod x^n)),向(998244353)取模。

    推式子

    首先我们对两边分别求导,得到:

    [G'(x)=ln(F(x))' ]

    复合函数求导公式为(f(g(x))'=f'(g(x))g'(x)),且众所周知(ln'(x)=frac 1x),因此就有:

    [G'(x)=frac 1{F(x)}*F'(x) ]

    其中,对于(F'(x)),可以根据((x^a)'=ax^{a-1})这一基本公式简单转化得到。

    然后,我们用多项式乘法逆求出(frac1{F(x)}),再用(NTT)(frac 1{F(x)})(F'(x))卷起来就可以得到(G'(x))了。

    接下来我们需要把(G'(x))变回(G(x))

    那么只需要执行求导操作的逆运算——积分,根据(int x^adx=frac1{a+1}x^{a+1})这一基本公式即可。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define X 998244353
    using namespace std;
    int n,a[N+5],b[N+5];
    I int QP(RI x,RI y) {RI t=1;W(y) y&1&&(t=1LL*t*x%X),x=1LL*x*x%X,y>>=1;return t;}
    namespace Poly
    {
    	#define Init(n) P=1,L=0;W(P<=2*(n)) P<<=1,++L;
    		for(i=0;i^P;++i) A[i]=B[i]=0,R[i]=(R[i>>1]>>1)|((i&1)<<L-1);//多项式卷积初始化
    	int PR=3,IPR=QP(3,X-2),P,L,R[4*N+5],A[4*N+5],B[4*N+5],p[4*N+5];
    	I void NTT(int *s,CI t)//NTT
    	{
    		RI i,j,k,x,y,U,S;for(i=0;i^P;++i) i<R[i]&&(x=s[i],s[i]=s[R[i]],s[R[i]]=x);
    		for(i=1;i^P;i<<=1) for(U=QP(t,(X-1)/(i<<1)),j=0;j^P;j+=i<<1) for(S=1,k=0;k^i;
    			S=1LL*S*U%X,++k) s[j+k]=((x=s[j+k])+(y=1LL*S*s[i+j+k]%X))%X,s[i+j+k]=(x-y+X)%X;
    	}
    	I void Inv(CI n,int *a,int *b)//多项式乘法逆
    	{
    		if(!n) return (void)(b[0]=1);RI i;Inv(n>>1,a,b);
    		Init(n);for(i=0;i<=n;++i) A[i]=a[i],B[i]=b[i];
    		for(NTT(A,PR),NTT(B,PR),i=0;i^P;++i) B[i]=(2LL*B[i]-1LL*A[i]*B[i]%X*B[i]%X+X)%X;
    		RI t=QP(P,X-2);for(NTT(B,IPR),i=0;i<=n;++i) b[i]=1LL*B[i]*t%X;
    	}
    	I void Ln(CI n,int *a,int *b)//多项式ln
    	{
    		RI i;for(i=n-1;~i;--i) p[i]=1LL*a[i+1]*(i+1)%X;Inv(n,a,b);//b存储a',p存储1/a
    		Init(n-1);for(i=0;i<=n-1;++i) A[i]=p[i],B[i]=b[i];
    		for(NTT(A,PR),NTT(B,PR),i=0;i^P;++i) A[i]=1LL*A[i]*B[i]%X;
    		RI t=QP(P,X-2);for(NTT(A,IPR),i=n-1;~i;--i) b[i+1]=1LL*A[i]*t%X*QP(i+1,X-2)%X;b[0]=0;//求出∫(b*p)即为答案
    	}
    }
    int main()
    {
    	RI i;for(scanf("%d",&n),--n,i=0;i<=n;++i) scanf("%d",a+i);//读入
    	for(Poly::Ln(n,a,b),i=0;i<=n;++i) printf("%d%c",b[i]," 
    "[i==n]);return 0;//输出
    }
    
  • 相关阅读:
    mysql练习题练习
    test
    jquery获取地址栏参数
    Sql Server获取数据库字段名,并用list显示在jsp页面
    javascript主页面获取子页面元素
    javascript常用方法
    jquery.cookie实现刷新页面复选框选定状态不变
    JDBC操作Oracle、SqlServer根据日期查询
    mysql 5.1升级为5.5方法
    innodb二进制文件相关的参数
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/PolyLn.html
Copyright © 2020-2023  润新知