zoukankan      html  css  js  c++  java
  • 【学习笔记】多项式对数函数

    求:

    [G(x)equiv ln F(x)(mod x^n) ]

    解:

    (f(x)=ln x)

    [G(x)equiv f(F(x))(mod x^n) ]

    两边求导:

    [G'(x)equiv frac{F'(x)}{F(x)}(mod x^n) ]

    所以,对(F)求一个逆,求一个导,乘起来再求一个逆就做完了。

    求导与积分:

    [f(x)=x^a,f'(x)=ax^{a-1} ]

    [int f(x) dx=frac{1}{a+1}x^{a+1} ]

    它们互为逆运算。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=300010;
    const int mod=998244353; 
    int a[N],b[N],c[N],rev[N],g[N],n,e[N],f[N];
    inline int add(int x,int y){return (x+y)%mod;}
    inline int mul(int x,int y){return 1ll*x*y%mod;}
    inline int qpow(int a,int b){
    	int res=1;
    	while(b){
    		if(b&1)res=mul(res,a);
    		a=mul(a,a);b>>=1;
    	}
    	return res;
    }
    void NTT(int *a,int n,int x){
    	for(int i=0;i<n;++i)if(i<rev[i])swap(a[i],a[rev[i]]);
    	for(int i=1;i<n;i<<=1){
    		int gn=qpow(3,(mod-1)/(i<<1));
    		for(int j=0;j<n;j+=(i<<1)){
    			int G=1,x,y;
    			for(int k=0;k<i;++k,G=mul(G,gn)){
    				x=a[j+k],y=mul(G,a[i+j+k]);
    				a[i+j+k]=add(x,mod-y);a[j+k]=add(x,y);
    			}
    		}
    	}
    	if(x==1)return;
    	int inv=qpow(n,mod-2);reverse(a+1,a+n);
    	for(int i=0;i<n;++i)a[i]=mul(a[i],inv);
    }
    void Getinv(int d,int *a,int *b){
    	if(d==1){b[0]=qpow(a[0],mod-2);return;}
    	Getinv((d+1)>>1,a,b);
    	int lim=1,len=0;
    	while(lim<(d<<1))lim<<=1,++len;
    	for(int i=1;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
    	for(int i=0;i<d;++i)c[i]=a[i];
    	for(int i=d;i<lim;++i)c[i]=0;
    	NTT(c,lim,1);NTT(b,lim,1);
    	for(int i=0;i<lim;++i)b[i]=1LL*(2-1ll*c[i]*b[i]%mod+mod)%mod*b[i]%mod;
    	NTT(b,lim,-1);for(int i=d;i<lim;++i)b[i]=0;
    }
    inline void Derivative(int *a,int *b,int L){for(int i=1;i<L;++i)b[i-1]=mul(i,a[i]);b[L-1]=0;}
    inline void Integral(int *a,int *b,int L){for(int i=1;i<L;++i)b[i]=mul(a[i-1],qpow(i,mod-2));b[0]=0;}
    void GetLn(int L,int *a){
    	Derivative(a,e,L);Getinv(L,a,f);
    	int lim=1,len=0;
    	while(lim<(L<<1))lim<<=1,++len;
    	for(int i=1;i<lim;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
    	NTT(e,lim,1);NTT(f,lim,1);
    	for(int i=0;i<lim;++i)e[i]=mul(e[i],f[i]);
    	NTT(e,lim,-1);Integral(e,g,lim);
    	for(int i=0;i<n;++i)printf("%d ",g[i]); 
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=0;i<n;++i)scanf("%d",&a[i]);
    	int LL=1;for(LL=1;LL<=n;LL<<=1);GetLn(LL,a);
    	return 0;
    }
    
  • 相关阅读:
    Linux用户配置文件、口令配置文件、组配置文件
    Linux忘记Root密码怎么找回
    Linux运行级别及解释
    Maven获取resources的文件路径、读取resources的文件
    常见状态码100、200、300、400、500等
    JVM内存模型
    tcl使用小结
    MFQ&&PPDCS
    总结下自己在工作中有关联的TCP/IP协议
    二层交换机和三层交换机
  • 原文地址:https://www.cnblogs.com/h-lka/p/13504159.html
Copyright © 2011-2022 走看看