拉格朗日插值
luogu 4781
金牌导航 拉格朗日插值-1
题目大意
给出n个点,让你确定经过这n个点且不超过n-1次的方程,现在给出k,让你求出其函数值
样例#1
输入样例#1
3 100
1 4
2 9
3 16
输出样例#1
10201
样例#2
输入样例#2
3 100
1 1
2 2
3 3
输出样例#2
100
数据范围
1⩽n⩽2×103,1⩽xi,yi,k⩽9982443531\leqslant n\leqslant 2\times 10^3,1\leqslant x_i,y_i,k\leqslant 9982443531⩽n⩽2×103,1⩽xi,yi,k⩽998244353
解题思路
直接代入拉格朗日插值公式即可(如下)
f(k)=∑i=0nyi∏i≠jk−xjxi−xjf(k)=\sum_{i=0}^{n}y_i\prod_{i\neq j}\frac{k-x_j}{x_i-x_j}f(k)=i=0∑nyii=j∏xi−xjk−xj
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 2010
#define wyc 998244353
using namespace std;
ll n, m, k, g1, g2, ans, x[N], y[N];
ll Counting(ll x, ll y)
{ll s = 1;while(y){if (y&1) s = s * x % wyc;x = x * x % wyc;y >>= 1;}return s;
}
int main()
{scanf("%lld%lld", &n, &k);for (ll i = 1; i <= n; ++i)scanf("%lld%lld", &x[i], &y[i]);for (ll i = 1; i <= n; ++i){g1 = 1;g2 = 1;for (ll j = 1; j <= n; ++j)//计算公式if (i != j){g1 = g1 * (k - x[j]) % wyc;g2 = g2 * (x[i] - x[j]) % wyc;}ans = (ans + y[i] * g1 % wyc * Counting(g2, wyc - 2) % wyc + wyc) % wyc;}printf("%lld", ans);return 0;
}