题解 P5158【【模板】多项式快速插值】

Link

题意

给出 n1 次多项式 F(x)n 个点值 F(xi)=yi,求出这个多项式 F(x)

1n105

思路

Update 2024.03.19:更改了代码与部分说明。

以下默认 mid=l+r2

回顾拉格朗日插值的式子:

F(x)=i=1nyiijxxjxixj

将后面的分母提到前面:

F(x)=i=1nyiijxixjij(xxj)

δ(x)=i=1n(xxi),则:

ij(xixj)=limxxiδ(x)xxi=δ(xi)

F(x)=i=1nyiδ(xi)ij(xxj)

δ(x) 容易分治 NTT 求出,然后使用多点求值求出 δ(xi),不会多点求值可以看这里

接下来直接分治 NTT 即可。具体地,设 Gl,r(x)=i=lr(xxi)Hl,r(x)(xl,yl),(xl+1yl+1),(xr,yr) 插出来的多项式,即 i=lryiδ(xi)ijljr(xxj),不难导出:

Gl,r(x)=Gl,mid(x)Gmid+1,r(x)

Hl,r(x)=Hl,mid(x)Gmid+1,r(x)+Hmid+1,r(x)Gl,mid(x)

每一步的时间复杂度均为 O(nlog2n),于是总时间复杂度为 O(nlog2n)

核心代码:

namespace Interpolation{
	#define ls (rt<<1)
	#define rs (rt<<1|1)
	inline Poly MulT(const Poly &a,const Poly &b){
		Poly F=a,G=b;
		int n=a.size(),m=b.size();
		reverse(G.begin(),G.end());
		init(n);
		F.resize(lim),G.resize(lim);
		NTT(F,1),NTT(G,1);
		for(int i=0;i<lim;i++)
			G[i]=1ll*F[i]*G[i]%mod;
		NTT(G,-1);
		for(int i=m-1;i<n;i++)
			F[i-m+1]=G[i];
		F.resize(max(0,n-m+1));
		return F;
	}
	Poly TR[N],T[N];
	Poly Q,QY,ans;
	inline void build(int rt,int l,int r){
		if(l==r){
			TR[rt]=(Poly){1,dec(0,Q[l])};
			T[rt]=TR[rt],reverse(T[rt].begin(),T[rt].end());
			return ;
		}
		int mid=l+r>>1;
		build(ls,l,mid),build(rs,mid+1,r);
		TR[rt]=TR[ls]*TR[rs];
		T[rt]=TR[rt],reverse(T[rt].begin(),T[rt].end());
	}
	inline void solve(int rt,int l,int r,Poly F){
		if(l==r){
			ans[l]=F[0];
			return ;
		}
		int mid=l+r>>1;
		solve(ls,l,mid,MulT(F,TR[rs]));
		solve(rs,mid+1,r,MulT(F,TR[ls]));
	}
	inline Poly solve(int rt,int l,int r){
		if(l==r)
			return (Poly){1ll*QY[l]*qpow(ans[l],mod-2)%mod};
		int mid=l+r>>1;
		Poly L=solve(ls,l,mid),R=solve(rs,mid+1,r);
		return L*T[rs]+R*T[ls];
	}
	inline Poly solve(Poly X,Poly Y){
		Q=X,QY=Y;
		int n=X.size();
		build(1,0,n-1);
		Poly F=Deriv(T[1]);
		ans.resize(n),F.resize(n*2);
		solve(1,0,n-1,MulT(F,Inv(TR[1])));
		return solve(1,0,n-1);
	}
}
posted @   ffffyc  阅读(8)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示