[学习笔记]多项式对数函数
第一次接触
感觉没有什么实际价值?这种定义也是不明不白?
先背板子好了
(upda:2019.2.6:好像就是指数函数的辅佐,ln就是一种表示,不像exp还是能展开的)
前置知识:
1.多项式积分,多项式求导
就是把多项式看成函数进行积分和求导
求导和不定积分互逆
也就是说
如果G(x)=F'(x),并且F(x)的常数项为0,
那么对G(x)进行积分,得到的就是F(x)
证明大概就是积分的求法:
要么是按照面积分成一块一块求
要么是找到导数是这个函数的函数的两个位置函数值做差
2.多项式求逆
一个条件是a0!=0
所以多项式有ln的前提条件是a0!=0
B(x)=lnA(x)
对两边同时求导
G'(F(x))=G'(u)*F'(x)(其中u=F(x))然后再回带
B'(x)=1/A(x)*A'(x)
然后对B'(x)做积分即可得到B(x)本身
(或者理解成直接找导数是B'(x)的B(x),由于式子都是ai*x^i的,所以很好找)
代码:
#include<bits/stdc++.h> #define il inline #define reg register int #define numb (ch^'0') #define int long long using namespace std; typedef long long ll; il void rd(int &x){ char ch;bool fl=false; while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true); for(x=numb;isdigit(ch=getchar());x=x*10+numb); (fl==true)&&(x=-x); } namespace Miracle{ const int N=8*1e5+5; const int mod=998244353; const int G=3; const int GI=332748118; int n; int f[N],p[N],ni[N]; int rev[N]; int qm(int x,int y){ int ret=1; while(y){ if(y&1) ret=(ll)ret*x%mod; x=(ll)x*x%mod; y>>=1; } return ret; } void NTT(int *f,int n,int c){ for(reg i=0;i<n;++i){ if(i<rev[i]) swap(f[i],f[rev[i]]); } for(reg p=2;p<=n;p<<=1){ ll gen; if(c==1) gen=qm(G,(mod-1)/p); else gen=qm(GI,(mod-1)/p); for(reg l=0;l<n;l+=p){ ll buf=1; for(reg k=l;k<l+p/2;++k){ ll tmp=(ll)buf*f[k+p/2]%mod; f[k+p/2]=(f[k]-tmp+mod)%mod; f[k]=(f[k]+tmp)%mod; buf=(ll)buf*gen%mod; } } } } void calc(int *f,int *g,int n){ for(reg i=0;i<n;++i){ rev[i]=rev[i>>1]>>1|((i&1)?n>>1:0); } NTT(f,n,1);NTT(g,n,1); for(reg i=0;i<n;++i) f[i]=(ll)f[i]*g[i]%mod; NTT(f,n,-1); int iv=qm(n,mod-2); for(reg i=0;i<n;++i) f[i]=(ll)f[i]*iv%mod; } void inv(int *f,int *g,int n){ if(n==1){ g[0]=qm(f[0],mod-2);return; } inv(f,g,n>>1); for(reg i=0;i<n;++i) p[i]=f[i]; for(reg i=n;i<2*n;++i) p[i]=0; for(reg i=0;i<2*n;++i){ rev[i]=rev[i>>1]>>1|((i&1)?n:0); } NTT(p,2*n,1);NTT(g,2*n,1); for(reg i=0;i<2*n;++i){ g[i]=(ll)((ll)2-(ll)g[i]*p[i]%mod+mod)%mod*g[i]%mod; } NTT(g,2*n,-1); int iv=qm(2*n,mod-2); for(reg i=0;i<n;++i) g[i]=(ll)g[i]*iv%mod; for(reg i=n;i<2*n;++i) g[i]=0; } void dao(int *f,int n){ for(reg i=0;i<n-1;++i){ f[i]=(ll)f[i+1]*(i+1)%mod; } f[n-1]=0; } void ji(int *f,int n){ for(reg i=n-1;i>0;--i){ f[i]=(ll)f[i-1]*qm(i,mod-2)%mod; } f[0]=0; } int main(){ rd(n); for(reg i=0;i<n;++i){ rd(f[i]); } int len,lp; for(lp=2*n,len=1;len<=lp;len<<=1); inv(f,ni,len>>1); dao(f,len>>1); calc(f,ni,len); ji(f,len); for(reg i=0;i<n;++i){ printf("%d ",f[i]); } return 0; } } signed main(){ Miracle::main(); return 0; } /* Author: *Miracle* Date: 2019/1/29 19:51:00 */