拉格朗日插值的優缺點 筆記 拉格朗日插值

2021-10-16 14:14:55 字數 4082 閱讀 4013

簡介

對於 \(k\) 次多項式函式 \(f(x)\)。

若已知 \(k+1\) 個點值,則可構造出多項式。

有:\[f(x) = \sum_^y_i\prod_}\dfrac

正確性詳見 拉格朗日插值。

正確性將 \(k + 1\) 個點值代入即可檢驗。

當 \(x=x_k\) 時,對 \(i\) 進行討論:

當 \(i\not =\) 時,存在乙個 \(j\) 滿足 \(j=k\)。

對於乘積項的分子 \(\prod\limits_}x-x_j\),當 \(j=k\) 時,\(x-x_j = 0\)。

對答案無貢獻。

當 \(i=k\) 時,乘積項變為 \(\prod\limits_}\dfrac\)。

其值恆等於 \(1\)。

模板題by:luckyblock

#include

#include

#include

#include

#define ll long long

const int marx = 2010;

const ll mod = 998244353;

ll ans, n, k, x[marx], y[marx];

inline int read()

int f = 1, w = 0; char ch = getchar();

for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;

for(; isdigit(ch); ch = getchar()) w = (w << 3) + (w << 1) + (ch ^ '0');

return f * w;

ll qpow(ll x, ll y, ll mod)

ll ret = 1;

for(; y; x = x * x % mod, y >>= 1)

if(y & 1) ret = ret * x % mod;

return ret;

int main()

n = read(), k = read();

for(int i = 1; i <= n; i ++) x[i] = read(), y[i] = read();

for(int i = 1; i <= n; i ++)

ll tmp = 1ll;

for(int j = 1; j <= n; j ++)

if(i != j) tmp = tmp * (x[i] + mod - x[j]) % mod;

tmp = qpow(tmp, mod - 2, mod);

for(int j = 1; j <= n; j ++)

if(i != j) tmp = tmp * (k + mod - x[j]) % mod;

tmp = tmp * y[i] % mod, ans = (ans + tmp) % mod;

printf("%lld", ans);

system("pause");

return 0;

自然冪數之和

定義前 \(n\) 個自然數 \(k\) 次冪的和為:

\[s_k(n) = \sum_^i^k

給定 \(n,k\),求 \(s_k(n)\)。

\(1\le n\le 10^9,\ 1\le k\le 10^6\)。

性質\(s_k(n)\) 為關於 \(n\) 的 \(k+1\) 次多項式。

證明考慮對 \(k\) 進行歸納。

當 \(k=0\) 時,\(s_k(n) = n\),結論成立。

當 \(k=d\) 時:

通過二項式定理化簡,提出一項相消,有:

\[\begin

&(i+1)^ - i^\\

= &\sum_^\left(\begind+1\\j\end\right)i^j - i^\\

= &\sum_^\left(\begind+1\\j\end\right)i^j

\end\]

對 \((i+1)^ - i^\) 求和,有:

\[\begin&\sum_^\left\ - i^\right\}\\=&\sum_^\sum_^\left(\begind+1\\j\end\right)i^j\end

發現 \(\left(\begind+1\\j\end\right)\) 只與 \(j\) 有關,調換求和順序,有:

\[\begin&\sum_^\sum_^\left(\begind+1\\j\end\right)i^j\\=&\sum_^\left(\begind+1\\j\end\right)\sum_^i^j\\=&\sum_^\left(\begind+1\\j\end\right)s_j(n)\end

化出了有趣的玩意。

展開左側 \(i^\) 的求和式相消,則有:

\[(n+1)^ - 1 = \sum_^\left(\begind+1\\j\end\right)s_j(n)

提出右側 \(j=d\) 時的 \(s_d(n)\):

\[\left(\begind+1\\d\end\right)s_d(n) = (n+1)^ -\sum_^\left\d+1\\j\end\right)s_j(n)\right\} - 1

二項式定理展開右側,並略做處理:

\[s_d(n) = \dfrac\left\^n^j -\sum_^\left\d+1\\j\end\right)s_j(n)\right\} - 1\right\}

對於右側,通過數學歸納得到 \(s_j(n)\) 為關於 \(n\) 的 \(j\) 次多項式。

則整個式子最高次項出現在 \(\sum\limits_^n^j\) 中,次數為 \(d+1\)。

得證。具體實現

由性質,\(s_k(n)\) 為關於 \(n\) 的 \(k + 1\) 次多項式,需要 \(k+2\) 個點值進行構造。

可以直接取 \(k+1\) 個點,按照定義計算出 \(s_k(n)\),構造多項式。

複雜度 \(o(k^2)\)?我覺得不行。

題目對選擇的點並沒有要求,考慮選取一段連續的點進行優化。

使 \(x_i = i\),則選擇的點集為 \(\\)。

按照定義遞推出來即可,複雜度 \(o(k \log k)\)。

考慮要求的點 \((n, s_k(n))\),將其代入插值公式,有:

\[s_k(n)= \sum_^s_k(i)\prod_}\dfrac

發現乘積項的分母與 \(n\) 無關,提出來:

\[s_k(n)= \sum_^s_k(i)\dfrac}}}(i-j)}

手玩一下乘積項的變化規律。

對於分母,\(j\le k +2\),在已知 \(i\) 時有:

\[\begin

&\dfrac}(i-j)}\\ =

&\dfrac\\=&(-1)^\dfrac

\end\]

可先預處理階乘再求逆元,快速得到分母的值。

對於分子,也暴力拆一波:

\[\begin

&\prod\limits_}\\

=& n(n-1) \dots (n-(i-1))(n-(i+1))\dots (n-(k+2))\\

=&(\prod_^(n-j)) (\prod_^(n-j))&

\end\]

考慮維護 \((n-j)\) 的 前/後 綴積,可快速得到分子的值。

則有:\[s_k(n)= \sum_^(-1)^s_k(i)\dfrac^(n-j)) (\prod\limits_^(n-j))}

複雜度\(o(k \log k)\) 處理 \(k+2\) 個連續點值。

\(o(n)\) 預處理前/後 綴積,階乘。

求逆元時可以 \(o(n)\) 預處理,也可以單次 \(o(\log k)\)。

總複雜度 \(o(k\log k)\)。

優缺點優點:簡單好寫,複雜度優秀,就感覺到快。

缺點:出現了除法,需要求逆元,需保證模數為質數。

若模數不為質數怎麼辦? 可利用 斯特林數/伯努利數 求解。

伯努利數求解方法 詳見 皎月半灑花的題解。

斯特林數求解方法 複雜度 \(o(k^2)\),無法通過本題,詳見 自然數冪之和 - luckyblock。

寫在最後

拉格朗日插值的優缺點 拉格朗日與牛頓插值法的比較

第頁共 頁拉格朗日插值法與牛頓插值法的比較 一 背景 在工程和科學研究 現的函式是多種多樣的。常常會遇到這樣的情況 在某個實際 問題中,雖然可以斷定所考慮的函式xf 在區間b a上存在且連續,但卻難以找到它的 解析表示式,只能通過實驗和觀測得到在有限個點上的函式值 即一張函式表 顯然,要利用這張函式...

拉格朗日插值與拉格朗日反演

模板 拉格朗日插值 拉格朗日插值法 f x sum limits 我們先把右邊那部分提出來看 ell x prod x x cdots x x cdots x 舉個例子吧 有二次函式上的三點 f 4 10,f 5 5.25,f 6 1 求 f 18 求出三個基本式 ell x ell x ell x...

拉格朗日插值

拉格朗日插值基函式 li x x x 0 x xi 1 x xi 1 x x n x i x0 xi xi 1 xi xi 1 xi xn 拉格朗日差值函式 ln x i 0 nyil i x 其中,x為缺失值對應的下表序號,ln x 為缺失值的插值結果,xi 為缺失值yi 的下表序號。對全部缺失值...