多项式专题
多项式
点值表示法和系数表示法
代数基本定理: 一个
多项式有点值表示法和系数表示法两种
- 系数表示法:
- 点值表示法:
定理: 一个n-1次多项式在n个不同点的取值唯一确定了该多项式
证明:
考虑反证法,假设命题不成立,则存在两个
令
也就是
已知多项式点值表示法求系数表示法的过程被称为插值
拉格朗日插值
问题
已知平面上
,求该在该曲线某一位置的取值
法1 高斯消元
略
法2 拉格朗日插值
已知
证明
同样,
由
由于
即
所以有
所以有
所以在模意义下
求某一点处的函数值
求出整个多项式
在x取值连续的时候的做法
由于
分母维护前缀积和后缀积
分子维护阶乘
时间复杂度:
求函数值
求多项式
由此,我们发现普通的拉格朗日插值在增减坐标时需要全部重新计算
并且对求多项式并没有任何的优化
所以考虑进行进一步的优化
重心拉格朗日插值法
设
则
那么这样有什么用呢?
对于
举个例子
对于多项式
所以有
还有系数
将系数乘在上面的式子中
将三个式子系数相加
即可得到
考虑一下这个过程,由于所除的
此外,如果我们想要新加入一个点
所以重心拉格朗日插值,在有关多项式求函数值、求多项式系数上完全优于高斯消元
单位根
单位根的性质
为什么我们需要傅里叶变换
多项式有两种表示方法——系数表示法和点值表示法
系数表示法就是经典的
我们在重心拉格朗日插值法中,已知任意
这也说明,这
对于多项式,
那么它有什么用呢?
已知两个多项式
我们发现这个过程是
是吗?
如果只是随机取点,点值表示转成系数表示的复杂度暂时只能做到
于是我们就需要
那么
- 把已知的一个多项式转化成对应的点值表示;
- 把已知的点值表示转换成对应的多项式。
复杂度都是
快速傅里叶变换
Part 1 DFT
设
则有
将
将
这也就意味着,如果可以求出
多项式最终会递归到只有一个常数项
这样就用
将点值表示后的两个多项式相乘得到它们乘积的点值表示
Part 2 IDFT
考虑如何将点值表示转成系数表示
令
设另一个向量(复数)为
即多项式
其中
式子:
设
将
一式
二式
二式相减得
当
当
考虑刚才推的式子
当
当
因此有
于是我们得到了点值与系数的关系式了
由
将 DFT 中的单位根改为
FFT的优化方法
三次变两次
考虑下面这个式子
令
我们一次 DFT 计算出
在 IDFT 一次就可以得到答案
蝴蝶变换
递归的常数太大
不失一般性的,设
的序列,在递归的第一层会将其拆分为
和
两部分。
也就是说对于任意的
换言之,当前
可以发现
然后就可以愉快地递推了
NTT快速数论变换
我们为什么需要NTT
参考对除法的处理,我们考虑将
于是我们要考虑如何将
考虑原根的定义
取模的过程很像是一个循环,这与我们单位根在复平面上绕圈的过程相仿
我们知道单位根有如下的性质
那么只有当原根与单位根性质完全相同时,我们才可以等价替换,定义
我们来检验一下
由费马小定理
由于原根互不相同和费马小定理,有
所以
注意只有当
常见的
469762049
998244353
1004535809
任意模数NTT
如果模数不是
有一个想法是我们可以先用
但是如果题目的系数大于
如
既然一个模数不够用,那我们直接参考哈希,将模数扩展成三个,只需要取三个模数,使其乘积大于极限情况,最后再用中国剩余定理合并就好了
注意在中国剩余定理时会爆long long,所以可以全部定义成__int128
分治NTT
问题
给定序列
其中
答案对
题解
直接暴力
如果直接
显然这是一个比暴力还要劣的解
所以我们考虑
要求区间
这是一个卷积的形式,可以利用
复杂度为
莫比乌斯变换与莫比乌斯反演
莫比乌斯变换
莫比乌斯反演
证明
由
可得
证毕。
合并卷积
定义
称
设
这启发我们计算
快速莫比乌斯变换
快速莫比乌斯变换FMT
要对所有的
定义
那么有
设集合
那么
因为
那么由加法原理即可知
那么我们递推
时间复杂度
void FMT(int *f)
{
for(int i=0;i<n;++i)
for(int j=0;j<(1<<n);++j)
if(j&(1<<i)) f[j]+=f[j^(1<<i)];
}
这个过程相当于高维前缀和
IFMT快速莫比乌斯反演
跟FMT一样,不断递推,不过变成了减法。
void IFMT(int *f)
{
for(int i=0;i<n;++i)
for(int j=0;j<(1<<n);++j)
if(j&(1<<i)) f[j]-=f[j^(1<<i)];
}
这个过程相当于高维差分
子集卷积
由于
因而可以将原集合按照元素个数分组,做
复杂度
快速沃尔什变换
与/或卷积
- 或卷积:
- 与卷积:
考虑如何求 和 的或卷积:
引理:
若
若
设
现在考虑已知
注意到
于是
因而做两遍高维前缀和再反推回去即可,复杂度
与卷积即改为高维后缀和
inline void FWT_and(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=-1
for(int mid=1;mid<limit;mid=mid<<1){
int n=mid<<1;
for(int j=0;j<limit;j+=n){
for(int k=0;k<mid;++k){
a[j+k]+=t*a[j+k+mid]%mod;
Mod(a[j+k]);
}
}
}
return ;
}
inline void FWT_or(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=-1
for(int mid=1;mid<limit;mid=mid<<1){
int n=mid<<1;
for(int j=0;j<limit;j+=n){
for(int k=0;k<mid;++k){
a[j+k+mid]+=t*a[j+k]%mod;
Mod(a[j+k+mid]);
}
}
}
return ;
}
异或卷积
快速沃尔什变换(FWT):
定义集合幂级数
那么有:
时间复杂度
inline void FWT_xor(ll *a,ll t,int limit){//FWT:t=1;IFWT:t=mpow(2,mod-2)
for(int mid=1;mid<limit;mid=mid<<1){
int n=mid<<1;
for(int j=0;j<limit;j+=n){
for(int k=0;k<mid;++k){
ll x=a[j+k],y=a[j+k+mid];
a[j+k]=t*(x+y)%mod;Mod(a[j+k]);
a[j+k+mid]=t*(x-y+mod)%mod;Mod(a[j+k+mid]);
}
}
}
return ;
}
多项式牛顿迭代
给定多项式
我们假设已经求出了
考虑
我们来考虑一件事情
对于
那么就有
递归计算即可
多项式 ln
已知一个多项式
解决这个问题之前,先介绍多项式求导和多项式积分
多项式求导
利用导数公式
其中
多项式积分
利用公式
计算即可
回到原问题
因此
多项式exp
问题
已知一个多项式
先对它两边
令
然后递归计算
多项式快速幂
给定
法1
直接快速幂套上多项式乘法,时间复杂度
法2
考虑到
于是我们可以考虑先计算
复杂度
多项式乘法的技巧
如果要求的形式长下面这个样子
这不是我们想要的卷积形式,于是可以考虑将
由于
多项式求逆
问题
给定多项式
做法
首先,易知
假设已经求出
因此
两边平方,变为模
同时乘
递归计算即可
时间复杂度
多项式除法(取模)
问题:
给定多项式
考虑构造系数翻转的变换
进行推导,设
此时我们发现,如果我们两边取模
即
多项式开方
问题:
给定多项式
解法
假设已经求出了
则有
递归计算即可
特征方程
一个数列
设有
那么
于是有
韦达定理构造方程得
这样解出
特征方程在一阶线性递推中的应用
设数列
设
那么
将
常系数齐次线性递推
问题
给定一个线性递推数列
的前
矩阵快速幂做法
我们构造它的初始矩阵为
加速矩阵为
由此,时间复杂度为
瓶颈在于如何快速求出加速矩阵
为了解决这个问题,我们可以引出常系数齐次线性递推
先介绍一些前置知识
特征值与特征向量
矩阵乘上列向量仍然是一个列向量
若对于矩阵
那么称
令
发现
又因为
将
那么有
我们设
写高级点
此时称
它也可以这样表示
特征多项式
考虑当
即对于矩阵
常系数齐次线性递推
前置知识说完了,考虑我们原先的问题
如何快速求出
我们将问题简化为求
考虑多项式除法/取模
其中
将其改为矩阵的形式
由
那么有
由多项式取模的定义,
所以我们把原来的矩阵
我们在两边乘上
然后,终于做完了!
posted on 2022-08-05 08:34 star_road_xyz 阅读(171) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效