zoukankan      html  css  js  c++  java
  • 并不对劲的多项式求ln,exp

    ln

    解释

    (g(x)=ln(f(x))),两边同时求导,则有:(g'(x)=ln'(f(x))*f'(x)=f^{-1}(x)*f'(x))(1)
    因为(f(x))是个多项式,所以设(f(x)=sum_{i=0}^{n}a_i*x^i),则有(f'(x)=sum_{i=0}^{n-1}a_{i+1}*(i+1)*x^i)
    (h(x)=f^{-1}(x)*f'(x)),对(1)式两边同时求积分,得:(g(x)=int h(x)space dx)
    因为(h(x))是个多项式,设(h(x)=sum_{i=0}^{n}b_i*x^i)就有:(int h(x)space dx=sum_{i=1}^{n}frac{b_{i-1}}{i}x^i)

    代码
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
    #define maxn 800010
    #define LL long long 
    #define mo(x) (x>=mod?x-mod:(x<0?x+mod:x))
    using namespace std;
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return x*f;
    }
    void write(int x)
    {
    	if(x==0){putchar('0');return;}
    	int f=0;char ch[20];
    	if(x<0)putchar('-'),x=-x;
    	while(x)ch[++f]=x%10+'0',x/=10;
    	while(f)putchar(ch[f--]);
    	return;
    }
    const LL mod=998244353;
    int f[maxn],g[maxn],h[maxn],nowlen,nown,r[maxn],tmp[maxn],n;
    int mul(int x,int y){int res=1;while(y){if(y&1)res=(LL)res*(LL)x%mod;x=(LL)x*(LL)x%mod,y>>=1;}return res;}
    void dnt(int * u,int fh)
    {
    	rep(i,0,nown-1)r[i]=(r[i>>1]>>1)|((i&1)<<(nowlen-1));
    	rep(i,0,nown-1)if(i<r[i])swap(u[i],u[r[i]]);
    	for(int i=1;i<nown;i<<=1)
    	{
    		int wn=mul(3,(mod-1)/(i<<1)); 
    		if(fh==-1)wn=mul(wn,mod-2);
    		for(int j=0;j<nown;j+=(i<<1))
    		{
    			int w=1;
    			rep(k,0,i-1){int x=u[j+k],y=(LL)w*(LL)u[i+j+k]%mod;u[j+k]=mo(x+y),u[i+j+k]=mo(x-y),w=(LL)w*(LL)wn%mod;}
    		}
    	}
    	if(fh==-1)
    	{
    		int inv=mul(nown,mod-2);
    		rep(i,0,nown-1)u[i]=(LL)u[i]*(LL)inv%mod;
    	}
    }
    void getny(int * u,int * v,int nlen)
    {
    	v[0]=mul(u[0],mod-2);
    	for(int len=0,tmpn=1;tmpn<nlen;len++,tmpn<<=1)
    	{
    		nown=tmpn<<1,nowlen=len+1;
    		rep(i,0,nown-1)tmp[i]=u[i];
    		nown<<=1,nowlen++;
    		rep(i,(tmpn<<1),nown-1)tmp[i]=0;
    		dnt(tmp,1),dnt(v,1);
    		rep(i,0,nown-1)v[i]=mo(2ll-(LL)tmp[i]*(LL)v[i]%mod)*(LL)v[i]%mod;
    		dnt(v,-1);
    		rep(i,(tmpn<<1),nown-1)v[i]=0;
    	}
    	rep(i,nlen,nown)v[i]=0;
    }
    void getup(int * u,int * v,int nlen)
    {
    	rep(i,1,nlen-1)v[i-1]=(LL)i*(LL)u[i]%mod;v[nlen-1]=0;
    }
    void getdx(int * u,int * v,int nlen)
    {
    	rep(i,1,nlen-1)v[i]=(LL)u[i-1]*(LL)mul(i,mod-2)%mod;v[0]=0;
    }
    void getln(int * u,int nlen)
    {
    	getup(u,h,nlen),getny(u,g,nlen);
    	for(nowlen=0,nown=1;nown<(nlen+nlen);nowlen++,nown<<=1);
    	dnt(h,1),dnt(g,1);
    	rep(i,0,nown-1)h[i]=(LL)h[i]*(LL)g[i]%mod;
    	rep(i,0,nown-1)g[i]=0;
    	dnt(h,-1);getdx(h,g,nlen);
    	rep(i,nlen,nown)g[i]=0;
    }
    int main()
    {
    	n=read();
    	rep(i,0,n-1)f[i]=read();
    	getln(f,n);
    	rep(i,0,n-1)write(g[i]),putchar(' ');
    	return 0;
    }
    

    exp

    解释

    这个人(点这里)讲得很清楚

    代码
    #include<algorithm>
    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<ctime>
    #include<iomanip>
    #include<iostream>
    #include<map>
    #include<queue>
    #include<set>
    #include<stack>
    #include<vector>
    #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
    #define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
    #define maxn 800010
    #define LL long long 
    #define mo(x) (x>=mod?x-mod:(x<0?x+mod:x))
    using namespace std;
    int read()
    {
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)&&ch!='-')ch=getchar();
    	if(ch=='-')f=-1,ch=getchar();
    	while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return x*f;
    }
    void write(int x)
    {
    	if(x==0){putchar('0');return;}
    	int f=0;char ch[20];
    	if(x<0)putchar('-'),x=-x;
    	while(x)ch[++f]=x%10+'0',x/=10;
    	while(f)putchar(ch[f--]);
    	return;
    }
    const LL mod=998244353;
    int f[maxn],g[maxn],h[maxn],ans[maxn],nowlen,nown,r[maxn],tmp[maxn],tmp2[maxn],n;
    int mul(int x,int y){int res=1;while(y){if(y&1)res=(LL)res*(LL)x%mod;x=(LL)x*(LL)x%mod,y>>=1;}return res;}
    void dnt(int * u,int fh)
    {
    	rep(i,0,nown-1)r[i]=(r[i>>1]>>1)|((i&1)<<(nowlen-1));
    	rep(i,0,nown-1)if(i<r[i])swap(u[i],u[r[i]]);
    	for(int i=1;i<nown;i<<=1)
    	{
    		int wn=mul(3,(mod-1)/(i<<1)); 
    		if(fh==-1)wn=mul(wn,mod-2);
    		for(int j=0;j<nown;j+=(i<<1))
    		{
    			int w=1;
    			rep(k,0,i-1){int x=u[j+k],y=(LL)w*(LL)u[i+j+k]%mod;u[j+k]=mo(x+y),u[i+j+k]=mo(x-y),w=(LL)w*(LL)wn%mod;}
    		}
    	}
    	if(fh==-1)
    	{
    		int inv=mul(nown,mod-2);
    		rep(i,0,nown-1)u[i]=(LL)u[i]*(LL)inv%mod;
    	}
    }
    void getny(int * u,int * v,int nlen)
    {
    	v[0]=mul(u[0],mod-2);
    	for(int len=0,tmpn=1;tmpn<nlen;len++,tmpn<<=1)
    	{
    		nown=tmpn<<1,nowlen=len+1;
    		rep(i,0,nown-1)tmp[i]=u[i];
    		nown<<=1,nowlen++;
    		rep(i,(tmpn<<1),nown-1)tmp[i]=0;
    		dnt(tmp,1),dnt(v,1);
    		rep(i,0,nown-1)v[i]=mo(2ll-(LL)tmp[i]*(LL)v[i]%mod)*(LL)v[i]%mod;
    		dnt(v,-1);
    		rep(i,(tmpn<<1),nown-1)v[i]=0;
    	}
    	rep(i,0,nown)tmp[i]=0; 
    	rep(i,nlen,nown)v[i]=0;
    }
    void getup(int * u,int * v,int nlen)
    {
    	rep(i,1,nlen-1)v[i-1]=(LL)i*(LL)u[i]%mod;v[nlen-1]=0;
    }
    void getdx(int * u,int * v,int nlen)
    {
    	rep(i,1,nlen-1)v[i]=(LL)u[i-1]*(LL)mul(i,mod-2)%mod;v[0]=0;
    }
    void getln(int * u,int * v,int nlen)
    {
    	getup(u,h,nlen),getny(u,g,nlen);
    	for(nowlen=0,nown=1;nown<(nlen+nlen);nowlen++,nown<<=1);
    	dnt(h,1),dnt(g,1);
    	rep(i,0,nown-1)h[i]=(LL)h[i]*(LL)g[i]%mod;
    	rep(i,0,nown-1)g[i]=0;
    	dnt(h,-1);getdx(h,v,nlen);
    	rep(i,nlen,nown)v[i]=0;
    }
    void getexp(int * u,int * v,int nlen)
    {
    	rep(i,0,(nlen<<2))v[i]=0;
    	v[0]=1;
    	for(int len=0,tmpn=1;tmpn<nlen;len++,tmpn<<=1)
    	{
    		rep(i,0,(tmpn<<1))tmp2[i]=0;
    		getln(v,tmp2,(tmpn<<1));
    		nown=(tmpn<<2),nowlen=len+2;
    		rep(i,(tmpn<<1),nown)tmp2[i]=0;
    		rep(i,0,(tmpn<<1)-1)tmp[i]=u[i];
    		rep(i,(tmpn<<1),nown)tmp[i]=0;
    		dnt(tmp2,1),dnt(v,1),dnt(tmp,1);
    		rep(i,0,nown-1)v[i]=(LL)v[i]*(LL)mo(mo(1ll-tmp2[i])+tmp[i])%mod;
    		dnt(v,-1);
    		rep(i,(tmpn<<1),nown)v[i]=0;
    	}
    	rep(i,nlen,nown)v[i]=0;
    }
    int main()
    {
    	n=read();
    	rep(i,0,n-1)f[i]=read();
    	getexp(f,ans,n);
    	rep(i,0,n-1)write(ans[i]),putchar(' ');
    	return 0;
    }
    
  • 相关阅读:
    Spring Cloud Hystrix(熔断器)介绍及使用
    Fign入门学习
    Ribbon入门学习
    浅谈JSON5
    JSONObject 与 JSON 互转
    Windows下安装使用jmeter
    MongoDB 数据库高级进阶
    Mysq-l数据库下载以及安装(至安装成功cmd可访问)
    Mysql-数据库下载
    端口占用
  • 原文地址:https://www.cnblogs.com/xzyf/p/10519392.html
Copyright © 2011-2022 走看看