初涉拉格朗日插值
通过多项式点值表示得到多项式在某一点的值。
什么是拉格朗日插值
就扔个式子先,证明先留坑。
拉格朗日插值的应用
通常来说,拉格朗日插值属于有点偏门的算法。
一般应用有:求$\sum{i^k}$的多项式;解矩阵的特征多项式等等。
推荐博客
Ebola的OI笔记:拉格朗日插值 学习笔记
板子题
P4781 【模板】拉格朗日插值
题目描述
由小学知识可知, nn 个点 (x_i,y_i)(xi,yi) 可以唯一地确定一个多项式
现在,给定 nn 个点,请你确定这个多项式,并将 kk 代入求值
求出的值对 998244353998244353 取模
输入输出格式
输入格式:
第一行两个正整数 n,kn,k ,含义如题
接下来 nn 行,每行两个正整数 x_i,y_ixi,yi ,含义如题
输出格式:
一个整数表示答案
说明
n \leq 2000 \; \; \; x_i,y_i,k \leq 998244353n≤2000xi,yi,k≤998244353
样例一中的三个点确定的多项式是 f(x)=x^2+2x+1f(x)=x2+2x+1 ,将 100100 代入求值得到 1020110201
样例二中的三个点确定的多项式是 f(x)=xf(x)=x ,将 100100 代入求值得到 100100
如果你不会拉格朗日插值,你可以到这里去学习一下
此外,请注意算法的常数问题,建议开启O2优化
题目分析
那么就是拉格朗日插值的最基础应用。
1 #include<bits/stdc++.h> 2 const int maxn = 2035; 3 const int MO = 998244353; 4 5 int x[maxn],y[maxn],n,k,ans; 6 7 int qmi(int a, int b) 8 { 9 int ret = 1; 10 while (b) 11 { 12 if (b&1) 13 ret = 1ll*ret*a%MO; 14 a = 1ll*a*a%MO, b >>= 1; 15 } 16 return ret; 17 } 18 int main() 19 { 20 scanf("%d%d",&n,&k); 21 for (int i=1; i<=n; i++) 22 scanf("%d%d",&x[i],&y[i]); 23 for (int i=1; i<=n; i++) 24 { 25 int upp = 1, low = 1; 26 for (int j=1; j<=n; j++) 27 { 28 if (i==j) continue; 29 upp = 1ll*upp*(k-x[j])%MO; 30 low = 1ll*low*(x[i]-x[j])%MO; 31 } 32 upp = (upp%MO+MO)%MO, low = (low%MO+MO)%MO; 33 ans = (ans+1ll*y[i]*upp%MO*qmi(low, MO-2)%MO)%MO; 34 } 35 printf("%d\n",ans); 36 return 0; 37 }
END