初涉拉格朗日插值

通过多项式点值表示得到多项式在某一点的值。

什么是拉格朗日插值

就扔个式子先,证明先留坑。

拉格朗日插值的应用

通常来说,拉格朗日插值属于有点偏门的算法。

一般应用有:求$\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 998244353n2000xi,yi,k998244353

样例一中的三个点确定的多项式是 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

posted @ 2018-08-07 16:18  AntiQuality  阅读(271)  评论(0编辑  收藏  举报