拉格朗日插值
-
\(f(x)\)为一个与\(x\)相关的\(n\)次多项式,\(x\)很大,但\(n\)次在时间允许的范围内,求一个值为\(O(n^2)\)
-
对于一个多项式,乘上一个值或加上一个值,\(n\)次都会变成\(n+1\)次
-
对于\(x_i\)为连续的数的情况,可以\(O(n)\)处理一个值(因为此时的\(\Sigma_{i=1}^n y_i* \prod_{j=1\&\&j\neq i}^n \frac{x-x_j}{x_i-x_j}\)可以直接表示为\(\Sigma_{i=1}^n y_i* \frac{\prod_{j=x-n}^{x-i-1}j*\prod_{j=x-i+1}^{x-1}j}{(-1)^{n-i}*(i-1)!*(n-i)!}\)所以这里直接预处理前缀积和后缀积即可
初始模板
for(int i=1;i<=n;++i){
ll a=1,b=1;
for(int j=1;j<=n;++j){
if(j==i) continue;
a=a*(k-x[j]+MOD)%MOD,b=b*(x[i]-x[j]+MOD)%MOD;
}
(ans+=1ll*y[i]*a%MOD*power(b,MOD-2)%MOD)%=MOD;
}
\(x_i\)为连续的数的情况
ll l(ll x,ll n,ll *y){
pre[0]=1;
for(ll i=1;i<=n;i++) pre[i]=pre[i-1]*(x-i+MOD)%MOD;
suf[n+1]=1;
for(ll i=n;i>=1;i--) suf[i]=suf[i+1]*(x-i+MOD)%MOD;
ll ans=0;
for(ll i=1;i<=n;i++) (ans+=y[i]*pre[i-1]%MOD*suf[i+1]%MOD*((n-i&1)?(MOD-1):1)%MOD*invf[i-1]%MOD*invf[n-i]%MOD)%=MOD;
return ans;
}
- 重心拉格朗日插值法
\[f(x)=\sum\limits_{i=1}^n y_i*\prod\limits_{j\neq i} \frac{x-x_j}{x_i-x_j}
\\=\sum\limits_{i=1}^n y_i* \frac{
\prod\limits_{j=1}^n x-x_j}{\prod\limits_{j\neq i}(x_i-x_j)\times (x-x_i)}
\\=\prod\limits_{i=1}^n (x-x_i)\sum\limits_{i=1}^n\frac{y_i}{\prod\limits_{j\neq i}(x_i-x_j)\times (x-x_i)}
\]
设\(\lambda=\prod\limits_{i=1}^n (x-x_i)\),则\(f(x)=\lambda \sum\limits_{i=1}^n\frac{y_i}{\prod\limits_{j\neq i}(x_i-x_j)\times (x-x_i)}\)
于是这个单词查询的时候就是\(O(n)\)的了,但预处理是\(O(n^2)\)的
for(int i=1;i<=n;++i){
iv[i]=1;
for(int j=1;j<=n;++j) if(i!=j) iv[i]=iv[i]*(x[i]-x[j]+MOD)%MOD;
}
int solve(int k){
int ans=0,t=1;
for(int i=1;i<=n;++i) t=t*(k-x[i]+MOD)%MOD,ans=(ans+y[i]*power(iv[i]*(k-x[i]+MOD)%MOD,MOD-2)%MOD)%MOD;
return ans*t%MOD;
}

浙公网安备 33010602011771号