题目描述:
题目背景
这是一道模板题
题目描述
由小学知识可知,n个点\((x_i,y_i)\)可以唯一地确定一个多项式
现在,给定n个点,请你确定这个多项式,并将k代入求值
求出的值对998244353取模
输入格式
第一行两个正整数n,k,含义如题
接下来nnn行,每行两个正整数x_i,y_i,含义如题
输出格式
一个整数表示答案
输入输出样例
输入 #1
3 100
1 4
2 9
3 16
输出 #1
10201
输入 #2
3 100
1 1
2 2
3 3
输出 #2
100
说明/提示
\(n≤2000xi,yi,k≤998244353n \leq 2000 \; \; \; x_i,y_i,k \leq 998244353n≤2000xi,yi,k≤998244353\)
样例一中的三个点确定的多项式是f(x)=x2+2x+1,将100代入求值得到10201
样例二中的三个点确定的多项式是f(x)=x,将100代入求值得到100
如果你不会拉格朗日插值,你可以到这里去学习一下
此外,请注意算法的常数问题,建议开启O2优化
思路:
拉格朗日插值的模板题,刚学了试一下
代码:
注意答案避免负数,加模再模一次
#include <iostream>
#define max_n 1000006
const long long mod = 998244353;
using namespace std;
int k;
int n;
long long fac[max_n];
long long x[max_n];
long long y[max_n];
long long pi = 1;
long long q_mod(long long a,long long b,long long mod)
{
long long res = 1;
while(b)
{
if(b&1)
{
res = (res*a)%mod;
}
a = (a*a)%mod;
b>>=1;
}
return res;
}
int main()
{
cin >> n >> k;
for(int i = 1;i<=n;i++)
{
cin >> x[i] >> y[i];
}
fac[0] = 1;
long long ans = 0;
for(int i = 1;i<=n;i++)
{
long long tmp = 1;
long long tmp2 = 1;
for(int j = 1;j<=n;j++)
{
if(i!=j)
{
tmp = tmp*(k-x[j])%mod;
tmp2 = (tmp2*(x[i]-x[j]+mod)%mod)%mod;
}
}
ans = (ans+y[i]*tmp%mod*q_mod(tmp2,mod-2,mod)%mod)%mod;
}
cout << (ans+mod)%mod << endl;
return 0;
}