拉格朗日差值学习笔记&做题记录

好像是多项式最基础的算法(?,但是咕了比较久,现在学一下吧。

差值是啥

这个东西类似于 FFT 的转化过程,就是多项式点值和多项式系数的转化,简而言之就是解决下面的问题,P4781

已知一个 \(n-1\) 次多项式的 \(n\) 个点值,\(f(x_i)=y_i\),已知 \(k\),求 \(f(k)\bmod 998244353\)

\(n\le 2000\)

咋做

显然可以直接列方程然后高斯消元,复杂度 \(O(n^3)\),非常寻宝。

考虑一个构造,令 \(F(x)=\sum f_i(x)\frac{y_i}{f_i(x_i)}\),其中 \(f_i(x)\) 是一个和 \(x_i\) 有关的多项式,满足 \(f_i(x_i)\ne 0,f_i(x_j)=0(j\ne i)\),这样就可以满足 \(F(x_i)=y_i\) 了,因为其他项全都是 \(0\)

再考虑怎么去构造这个 \(f_i(x)\)

因为显然 \(x_i\) 互不相同,所以可以构造出:

\[f_i(x)=\prod_{j\ne i}(x-x_j) \]

最后整理一下,可以得到:

\[F(k)=\sum_{i=1}^n y_i \frac{\prod_{j\ne i}(k-x_j)}{\prod_{j\ne i} (x_i-x_j)} \]

直接计算,时间复杂度 \(O(n^2)\)

code


  • 点值连续差值

上面部分相当于一个前缀乘上一个后缀可以直接预处理,下面部分相当于每次一个阶乘乘上一些 \(-1\),可以列出:

\[F(k)=\sum_{i=1}^n y_i \frac{\prod_{j\ne i}(k-x_j)}{(i-1)!(n-i)!(-1)^{n-i}} \]

时间复杂度 \(O(n)\)


  • 求系数

上面的做法可以查询出一个值,但是这个多项式具体是啥呢。

其实也很简单,考虑主要麻烦的是 \(\prod_{j\ne i}(k-x_j)\),可以先算 \(\prod (k-x_i)\) 然后再去除就好了。


做题记录

CF622F *2600

已知 \(n,k\),求 \(\sum_{i=1}^n i^k\)

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

比较板子的题。

考虑设 \(f(x)=\sum_{i=1}^x i^k\),最后要求的就是 \(f(n)\)

考虑 \(f(x)\) 的次数是多少,考虑差分一下,\(f(x)-f(x-1)=x^k\),这是个 \(k\) 次项式子,那么根据多项式基本知识,前缀和次数加一,所以原式是 \(k+1\) 次多项式。

所以直接差值,然后用点值连续的做就好了。

code


P5667

已知 \(n,m\),以及 \(f(0),f(1)\dots f(n)\),求 \(f(m),f(m+1)\dots f(m+n)\)

\(n\le 160000,n<m\le 10^8\)

求连续点值可以做到 \(O(n^2)\),寄。

发现要求的点值连续,考虑直接推式,此处为了方便先把 \(n\) 加一。

\[f(k)=\sum_{i=1}^n y_i\frac{k!}{(k-n)!(k-i+1)(i-1)!(n-i)!(-1)^{n-i}} \]

这个式子和上面的本质相同。

\[f(k)=\frac{k!}{(k-n)!}\sum_{i=1}^n \frac{y_i}{(k-i+1)(i-1)!(n-i)!(-1)^{n-i}}\\ =\frac{k!}{(k-n)!}\sum_{i=1}^n \frac{y_i}{(i-1)!(n-i)!(-1)^{n-i}}\frac{1}{k-i+1}\\ \]

直接卷积即可。

code


posted @ 2022-07-06 19:20  houzhiyuan  阅读(94)  评论(0编辑  收藏  举报