题解 P5158 【【模板】多项式快速插值】
Great_Influence · · 题解
想要解决这个问题,你得先知道多项式多点求值和拉格朗日插值。
知道拉格朗日插值,你就能够在
不过,我们可以尝试优化插值的过程。
先看拉格朗日插值的过程。
我们将它分成两个部分去计算。
先计算
设
然后,我们将式子拆开。
设
递归求解即可。时间复杂度
核心代码:
static int fst[MAXN];
void calcf(int*x,int l,int r,int lev)
{
if(l==r){pol[lev][0]=fst[l];return;}
int mid=(l+r)>>1;
calcf(x,l,mid,lev+1);
calc(x,mid+1,r,0,0);//这是分治乘法
mul(pol[lev+1],solv[0][0],pol[lev],mid-l,r-mid);//这是多项式乘法
calcf(x,mid+1,r,lev+1);
calc(x,l,mid,0,0);
mul(pol[lev+1],solv[0][0],Q,r-mid-1,mid-l+1);
Rep(i,0,r-l)pol[lev][i]=ad(pol[lev][i],Q[i]);
}
inline void getfunc(int*x,int*y,int*F,int n)
{
calc(x,1,n,0,0);
Rep(i,0,n)pol[0][i]=solv[0][0][i];
Deriv(pol[0],pol[0],n);//这是求导
getnum(x,fst,1,n,0,n-1);//这是多点求值
Rep(i,1,n)fst[i]=(ll)y[i]*power(fst[i],mod-2)%mod;
calcf(x,1,n,0);//主函数
Rep(i,0,n-1)F[i]=pol[0][i];
}