一般形式
对于
n
n
阶多项式,给定二维平面上互不相同的
n+1
n
+
1
个点
(xi,f(xi))(0≤i≤n)
(
x
i
,
f
(
x
i
)
)
(
0
≤
i
≤
n
)
,那么由拉格朗日插值法可得:
f(x)=∑ni=0f(xi)∏nj=0,j≠ix−xjxi−xj
f
(
x
)
=
∑
i
=
0
n
f
(
x
i
)
∏
j
=
0
,
j
≠
i
n
x
−
x
j
x
i
−
x
j
可以观察到
f(x)
f
(
x
)
在
(x0,x1,..,xn)
(
x
0
,
x
1
,
.
.
,
x
n
)
上都是成立的。
唯一性
可以证明,对于
n
n
阶多项式,存在二维平面上互不相同的
n+1
n
+
1
个点使得该多项式通过拉格朗日插值法表示后具有唯一性。
由拉格朗日插值的一般形式计算得到一个
n
n
阶多项式。将每项的系数带入,可以得到一个范德蒙德矩阵,而阶范德蒙德矩阵的行列式一定不为0,所以存在逆矩阵。
矩阵的逆矩阵具有唯一性,反之存在逆矩阵的矩阵也具有唯一性。所以
f(x)
f
(
x
)
具有唯一性。
应用
可以在
O(n2)
O
(
n
2
)
的时间内通过给定的
n+1
n
+
1
个点求出
n
n
阶多项式在某一点
k
k
上的取值。
同样,若该式具有一定特殊性,如给定的点是
x
x
轴上连续的一端,那么可以在时间内求解。
但注意拉格朗日插值法求多项式对手算很不友好。且多用于多项式单点求值,而非求解多项式。
典例
给定
n,k
n
,
k
。
(n≤107,k≤105)
(
n
≤
10
7
,
k
≤
10
5
)
求:
∑ni=1ik
∑
i
=
1
n
i
k
这题的复杂度通过巧妙的拉格朗日插值的运用可以从
O(nlogk)
O
(
n
log
k
)
降到
O(k)
O
(
k
)
。
考虑到可以将这种形式的式子转化为
k
k
阶多项式。而求的是
f(n)
f
(
n
)
的答案。
那么直接暴力求出前
k
k
项带入拉格朗日插值一般形式算出即可。
因为是连续的,所以求解时的连乘就变成了阶乘,化简整理后可得:
f(x)=∏ki=1(x−i)∑kj=1f(j)1(j−1)!(−1)k−j(k−j)!(x−j)
f
(
x
)
=
∏
i
=
1
k
(
x
−
i
)
∑
j
=
1
k
f
(
j
)
1
(
j
−
1
)
!
(
−
1
)
k
−
j
(
k
−
j
)
!
(
x
−
j
)
代码
传送门:洛谷:【模板】拉格朗日插值
#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int x[2002],y[2002],n,k,ans;
inline int ad(int x,int y){x+=y;if(x>=mod) x-=mod;return x;}
inline int dc(int x,int y){x-=y;if(x<0) x+=mod;return x;}
inline int mul(int x,int y){return 1ll*x*y%mod;}
template<class T>
inline void rd(T &x)
{
char c=getchar();int f=0;x=0;
while(!isdigit(c)) {if(c=='-') f=1;c=getchar();}
while(isdigit(c)) {x=x*10+(c^48);c=getchar();}
if(f) x=-x;
}
inline int fp(int x,int y)
{
int re=1;
for(;y;y>>=1,x=mul(x,x))
if(y&1) re=mul(re,x);
return re;
}
int main(){
int i,j,res,rep;
rd(n);rd(k);
for(i=1;i<=n;++i) rd(x[i]),rd(y[i]);
for(i=1;i<=n;++i){
res=y[i];rep=1;
for(j=1;j<=n && res!=0;++j) if(i!=j){
res=mul(dc(k,x[j]),res);
rep=mul(rep,dc(x[i],x[j]));
}
ans=ad(ans,mul(res,fp(rep,mod-2)));
}
printf("%d\n",ans);
}