【 前 置 知 识 】 \color{green}{【前置知识】} 【前置知识】
- 快速幂( O ( log n ) O(\log n) O(logn))
- 利用快速幂求逆元
【 算 法 略 讲 】 \color{green}{【算法略讲】} 【算法略讲】
【 模 板 链 接 】 : \color{blue}{【模板链接】:} 【模板链接】: 洛谷P4781
【 算 法 略 讲 】 : \color{blue}{【算法略讲】:} 【算法略讲】: 所谓的拉格朗日插值算法,就是证明了,当直线 y = f ( x ) y=f(x) y=f(x)经过了 n n n个点 ( x 1 , y 1 ) , ( x 2 , y 2 ) ⋯ ( x n , y n ) (x_1,y_1),(x_2,y_2) \cdots (x_n,y_n) (x1,y1),(x2,y2)⋯(xn,yn)时,对于任意的 t t t有:
f ( t ) = ∑ i = 1 n ( Π j = 1 n t − x j x i − x j ( i ≠ j ) ) f(t)=\sum\limits_{i=1}^{n} (\Pi^{n}_{j=1} \dfrac{t-x_j}{x_i-x_j}(i \neq j)) f(t)=i=1∑n(Πj=1nxi−xjt−xj(i=j))
直接代入 t = k t=k t=k求解,加以逆元辅助即可。时间复杂度 O ( n 2 ) O(n^2) O(n2)。
【 代 码 】 : \color{blue}{【代码】:} 【代码】:
const int mod=998244353;
int ksm(int a,int b){
register int ret=1;
while (b){
if (b&1) ret=1ll*ret*a%mod;
a=1ll*a*a%mod;b>>=1;
}
return ret;
}//快速幂算法
const int N=2010;
int n,k,ans,x[N],y[N];
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
scanf("%d%d",&x[i],&y[i]);
// 输入n个点(xi,yi)
for(int i=1;i<=n;i++){
int s1=y[i]%mod,s2=1;
for(int j=1;j<=n;j++)
if (i!=j){//注意边界条件,否则将RE
s1=1ll*s1*((k-x[j]+mod)%mod)%mod;
s2=1ll*s2*((x[i]+mod-x[j])%mod)%mod;
}
ans=(1ll*ans+(1ll*s1*ksm(s2,mod-2)%mod))%mod;
// 注意中间结果可能会爆int,需要中转long long求值
}
printf("%d",ans);
return 0;
}