LOJ #165. 拉格朗日插值
阿新 • • 發佈:2020-08-15
重心拉格朗日插值模板題。
用上面那篇文章的公式計算。插入時更新每個 \(w_i\),詢問時分別 \(O(n)\) 計算 \(l(k)\) 和 \(\sum\limits_{i=1}^n \frac{w_i}{k-x_i}\) 即可。注意使用上述公式時 \(k-x_i\) 不能為 \(0\),所以我們要特判 \(k=x_i\) 的情況。
程式碼:
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #define int long long using namespace std; const int N=3009,M=998244353; int n,cnt,x[N],y[N],w[N]; void init() { scanf("%lld",&n); } int ksm(int a,int b) { int res=1; while(b) { if(b&1) res=res*a%M; b>>=1,a=a*a%M; } return res; } void work() { int opt,X,Y; while(n--) { scanf("%lld",&opt); if(opt==1) { scanf("%lld %lld",&X,&Y); x[++cnt]=X,y[cnt]=w[cnt]=Y; for (int i=1;i<cnt;i++) w[i]=w[i]*ksm(x[i]-x[cnt],M-2)%M, w[cnt]=w[cnt]*ksm(x[cnt]-x[i],M-2)%M; } else { scanf("%lld",&X); int flag=0; for (int i=1;i<=cnt;i++) if(X==x[i]) { flag=1,printf("%lld\n",y[i]); break; } if(flag) continue; int tmp=1,_tmp=0; for (int i=1;i<=cnt;i++) tmp=tmp*(X-x[i])%M; for (int i=1;i<=cnt;i++) _tmp=(_tmp+w[i]*ksm(X-x[i],M-2)%M)%M; printf("%lld\n",(tmp*_tmp%M+M)%M); } } } signed main() { init(); work(); return 0; }