拉格朗日插值小记
对于 \(n\) 个点 \((x_i,y_i)\),\(x_i\) 互不相同,则我们可以 唯一 确定一个 \(n-1\) 次多项式经过这 \(n\) 点。
1. 拉格朗日插值
拉格朗日插值的核心思想是每次只考虑一个点值,将其他点值都视作 \(0\),即对于每一个点 \((x_i,y_i)\),我们构造一个函数 \(f_i(x)\)。
- 当且仅当 \(x = x_i\) 时 \(f_i(x) = y_i\),当 \(x = x_j(j \not = i)\) 时,\(f_i(x) = 0\)。
这样我们可以构造出经过所有点的函数 \(f(x) = \sum f_i(x)\)。
则我们首先对于每个点 \((x_i,y_i)\),设 \(f_i(x) = \prod\limits_{j \not = i}(x - x_j)\),则显然可以满足上述条件,而我们又要满足 \(f(x_i) = y_i\),则我们可以构造:
这样我们可以轻松的用 \(\mathcal{O}(n^2)\) 的复杂度解决。
直接套式子即可,逆元可以乘完再逆,写的时候脑子宕机了。
int main(){
n = read(),k = read();
for(int i = 1;i <= n;i++)x[i] = read(),y[i] = read();
ll ans = 0;
for(int i = 1;i <= n;i++){
ll s = y[i] % mod;
for(int j = 1;j <= n;j++){
if(i == j)continue;
s = s * (k - x[j] + mod) % mod;
s = s * ksm((x[i] - x[j] + mod) % mod,mod - 2) % mod;
}
(ans += s) %= mod;
}
printf("%lld\n",ans);
return 0;
}
2. 一些小优化
当这些点值是 \((i,y_i)\) 时,则我们可以分开处理 \(\prod\limits_{i \not = j}x - j\) 与 \(\prod\limits_{i \not = j}i - j\)。
前者我们可以首先算出 \(\prod \limits x - j\),求的时候除个 \((x - i)\) 即可。
后者我们可以分成 \(j < i\) 与 \(j > i\) 两个部分,求出答案是 \((i-1)! \times (n-i)! (-1)^{n-i}\)。
预处理逆元,复杂度 \(\mathcal{O}(n\log{V})\)。
例题: CF622F The Sum of the k-th Powers
即求 \(\sum\limits_{i=1}^n i^k\)。
\(n\) 太大,我们考虑关于 \(k\) 的复杂度。
首先我们可以知道这是一个关于 \(n\) 的 \(k+1\) 次多项式,我们只需要暴力求出前 \(k+2\),即可拉插,复杂度 \(\mathcal{O}(n\log{V})\)
-
如何证明是一个 \(k+1\) 次多项式呢?
我们可以归纳证明: 首先懒得奠基。
假设该结论对所有 \(k < m\) 都成立,则现在证明 \(k = m\) 时成立。
首先有 \((i+1)^{m + 1} - i^{m + 1} = \sum\limits_{j=0}^m\dbinom {m+1} j i^j\)。
我们对所有的 \(i\) 求和,左边是个裂项,答案为 \((n+1)^{m+1} - 1\)。
有 $$(n + 1)^{m+1} - 1 = \sum_{i=1}^{n} \sum_{j=0}^m \dbinom {m+1} j i^j = \sum_{j=0}^m\dbinom {m+1} j \sum_{i=1}^n i^j$$
把右边 \(j = m\) 移项得 $$\sum_{i=1}^{n} i^m = (n + 1)^{m+1} - 1 - \sum_{j=0}^{m-1}\dbinom {m+1} j \sum_{i=1}^n i^j$$
左半部分次数为 \(m + 1\),右半部分最大次数为 \(m - 1 + 1 = m\),证毕。
3. 多项式快速插值
不会
4. 例题
I CF622F The Sum of the k-th Powers
上述。
代码
首先我们考虑 DP,不妨设 \(a_i < a_{i+1}\),这样我们最后乘个 \(n!\) 即可。
设 \(f_{i,j}\) 表示值域为 \([1,i]\) 且序列长度为 \(j\) 时的答案。
则有转移方程 \(f_{i,j} = f_{i-1,j} + f_{i-1,j-1} \times i\),直接写复杂度是 \(\mathcal{O}(kn)\) 的,无法通过。
我们可以发现 \(f_{i,j}\) 可以视为 一个关于 \(i\) 的比较小次数的多项式,我们考虑分析一下其次数。
-
由转移方程得,\(f_{i,j} - f_{i-1,j} = f_{i-1,j-1} \times i\)。
首先有对于一个 \(k\) 次多项式 \(f(x)\),则 \(f(x+1) - f(x)\) 是一个 \(k-1\) 次多项式,可以二次项定理拆开简单证明。
\(f_{i,j}\) 的次数 \(-1\) 等于 \(f_{i,j-1}\) 的次数 \(+1\),又有 \(f_{i,0}\) 是一个 \(0\) 次多项式,可得 \(f_{i,j}\) 是一个关于 \(i\) 的 \(2j\) 次多项式。
则我们求出前 \(2n+1\) 个 DP 值,拉插一下即可。
复杂度 \(\mathcal{O}(n^2)\)。
III BZOJ3453: tyvj 1858 XLkxc
题意,给定 \(k,n,d,a\),\(k \leq 123\),\(n,d,a \leq 123456789\),求 $$\sum_{i=0}^{n} \sum_{j=1}^{a+id} \sum_{p=1}^{j} p^k$$
首先 \(f(x) = \sum\limits_{i=1}^{x}i^k\) 是一个 \(k+1\) 多项式,则 \(g(x) = \sum\limits_{i=1}^{x}f_i\) 是一个 \(k+2\) 次多项式,都可以 拉插 求出。
最后答案即为 \(\sum\limits_{i=0}^{n}g(a+id)\),答案最多是一个关于 \(n\) 的 \(k+3\) 次多项式,也可以 拉插,可以求出前 \(k+4\) 项,其中 \(g(x)\) 在内部也可以拉插求,总复杂度 \(\mathcal{O}(k^3)\),利用 2. 的技巧可以优化到 \(\mathcal{O}(k^2)\)。
没有代码。