拉格朗日插
拉格朗日插值:給定 \(n+1\) 個點 \((x_i,y_i)\),確定一個 \(n\) 次多項式 \(f\) 對其求值。
\[f(k)=\sum_{i=0}^{n}y_i \prod_{i\neq j}\frac{k-x_j}{x_i-x_j}
\]
正確性可以透過帶入 \(x_i\) 驗證,配合小學數學知識。
cin >> n >> k, --n;
up(i,0,n) cin >> x[i] >> y[i];
up(i,0,n) up(j,0,n) inv[i][j]=ksm(x[i]-x[j],P-2);
up(i,0,n) {
int mul=y[i];
up(j,0,n) if(i^j) mul=mul*(k-x[j])%P*inv[i][j]%P;
f=(f+mul)%P;
}
cout << (f%P+P)%P;
連續取值的拉格朗日插
連續取值的拉格朗日插:
\[f(k)=\sum_{i=0}^{n}y_i\prod_{i\neq j}\frac{k-j}{i-j}
\]
考慮處理 \(pre[i]=\prod_{j=0}^{i}k-j,suf[i]=\prod_{j=i}^n k-j,fac[i]=\prod_{j=0}^ii\),那麼有如下柿子,注意 \(n-i\) 為奇數時應取負號 >w<
\[f(k)=\sum_{i=0}^n y_i\frac{pre[i-1]\times suf[i+1]}{fac[i-1]\times fac[n-i]}
\]
k 次冪和
觀察可得 \(\sum_{i=1}^n i^k\) 是一個 \(k+1\) 次多項式可以帶入 \(k+2\) 個值拉插求求,複雜度 \(O(n)\)。證明本來想要因為我又菜又笨又懶就算了,啊啊啊看官見笑了嗚嗚嗚誒誒誒誒誒誒(
inv[0]=inv[1]=mul[0]=1;
up(i,2,2e6) inv[i]=inv[P%i]*(P-P/i)%P;
up(i,1,2e6) mul[i]=mul[i-1]*inv[i]%P;
cin >> n >> k, pre[0]=n, suf[k+1]=n-k-1;
up(i,1,k+1) pre[i]=pre[i-1]*(n-i)%P;
dn(i,k, 0) suf[i]=suf[i+1]*(n-i)%P;
up(i,0,k+1) {
y=(y+ksm(i,k))%P;
int qwq=((k+i)&1)?y:-y;
if(i>0) qwq=qwq*pre[i-1]%P*mul[i]%P;
if(i<k+1) qwq=qwq*suf[i+1]%P*mul[k+1-i]%P;
out=(out+qwq)%P;
}
cout << (out+P)%P;
重心拉格朗日插
\[f(k)=\sum_{i=0}^n y_i \prod_{i\neq j} (k-x_i) \prod_{i\neq j} \frac{1}{x_i-x_j}
\]
其實就是這樣子求值快一點點。