拉格朗日差值学习笔记&做题记录
好像是多项式最基础的算法(?,但是咕了比较久,现在学一下吧。
差值是啥
这个东西类似于 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\) 互不相同,所以可以构造出:
最后整理一下,可以得到:
直接计算,时间复杂度 \(O(n^2)\)。
- 点值连续差值
上面部分相当于一个前缀乘上一个后缀可以直接预处理,下面部分相当于每次一个阶乘乘上一些 \(-1\),可以列出:
时间复杂度 \(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\) 次多项式。
所以直接差值,然后用点值连续的做就好了。
已知 \(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\) 加一。
这个式子和上面的本质相同。
直接卷积即可。