多项式对数函数|指数函数(多项式)

多项式对数函数|指数函数

这个思路就是先求导然后再积分,这样就可以得到一个式子,对于多项式对数函数,我们就可以直接求解了,然后对于多项式指数函数还需要使用分治fft。

多项式对数:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
inline int read()
{
	char x='\0';
	int fh=1,sum=0;
	for(x=getchar();x<'0'||x>'9';x=getchar())if(x=='-')fh=-1;
	for(;x>='0'&&x<='9';x=getchar())sum=sum*10+x-'0';
	return fh*sum;
}
const int N=400009;
const int mod=998244353;
int n,m;
inline int ksm(int a,int b)
{
	int sum=1;
	while(b)
	{
		if(b&1)sum=1LL*sum*a%mod;
		b>>=1;
		a=1LL*a*a%mod;
	}
	return sum;
}
int F[N],G[N],rev[N],l,tt;
inline void getl(int len)
{
	for(l=1,tt=0;l<=len;l<<=1)tt++;
	for(int i=0;i<l;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(tt-1));
}
inline void NTT(int *P,int op)
{
	for(int i=0;i<l;i++)if(i<rev[i])swap(P[i],P[rev[i]]);
	for(int i=1;i<l;i<<=1)
	{
		int wn=ksm(3,(mod-1)/(i<<1));
		if(op<0)wn=ksm(wn,mod-2);
		for(int j=0,p=i<<1;j<l;j+=p)
		{
			for(int k=0,w=1;k<i;k++,w=1ll*w*wn%mod)
			{
				int x=P[j+k],y=1LL*P[j+i+k]*w%mod;
				P[j+k]=(x+y)%mod,P[j+i+k]=(x-y+mod)%mod;
			}			
		}
	}
	if(op<0)for(int i=0,u=ksm(l,mod-2);i<l;i++)P[i]=1LL*P[i]*u%mod;
}
int C[N],D[N];
inline void getinv(int *f,int *g,int n)
{
	if(n==1)return g[0]=ksm(f[0],mod-2),void();
	getinv(f,g,n>>1);
	getl(n);
	for(int i=0;i<n;i++) C[i]=f[i],D[i]=g[i];
	for(int i=n;i<l;i++) C[i]=D[i]=0;	NTT(C,1),NTT(D,1);
	for(int i=0;i<l;i++) C[i]=1LL*C[i]*D[i]%mod*D[i]%mod;	NTT(C,-1);
	for(int i=0;i<n;i++) g[i]=((2LL*g[i]%mod-C[i])%mod+mod)%mod;
}
void dao(int *A,int *B,int len)
{
	for(int i=1;i<len;i++)B[i-1]=1LL*i*A[i]%mod;
	B[len-1]=0;
}
void jifen(int *A,int *B,int len)
{
	for(int i=1;i<len;i++)B[i]=1LL*A[i-1]*ksm(i,mod-2)%mod;
	B[0]=0;
}
int A[N],B[N];
void getln(int *f,int *g,int n)
{
	dao(f,A,n);
	getinv(f,B,n);
	getl(n),NTT(A,1),NTT(B,1);
	for(int i=0;i<l;i++)A[i]=1LL*A[i]*B[i]%mod;
	NTT(A,-1);
	jifen(A,g,n);
}
int main()
{
	n=read();
	for(int i=0;i<n;i++)F[i]=read();
	for(m=1;m<=n;m<<=1); getln(F,G,m);
	for(int i=0;i<n;i++) printf("%d ",G[i]);
	return 0;
}


细节:

  1. 首先需要一个封装好的NTT,然后每次需要重新求解l和rev
  2. 对于中间数组需要用到ABCD4个,但是使用过程中不能直接清空,所以在每次使用的时候要将空余的位置设置为0,保证有效位置都是正确的
  3. 过程中直接传递指针,就可以递归求解了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值