多项式
简单来说做的就是多项式乘法,能够将多项式乘法的时间复杂度从
将多项式按照奇偶项分开
每次选择单位圆上的点所表示的复数带入计算即可。
可以发现一个规律:系数不断递归下去最终的位置将会是其二进制翻转后所表示的数。
代码模板如下:
inline void FFT(cp *a,int n,int inv) {
while(t<=n) t<<=1; while((1<<bit)<t) bit++;
for(int i=0;i<t;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1);
for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
for(int mid=1;mid<n;mid*=2) {
cp w=cp{cos(pi/mid),inv*sin(pi/mid)};
for(int i=0;i<n;i+=2*mid) {
cp o=cp{1,0};
for(int j=0;j<mid;j++,o=o*w) {
cp x=a[i+j], y=o*a[i+j+mid];
a[i+j]=x+y; a[i+j+mid]=x-y;
}
}
}
}
整数
找原根的方法:
将模数
模板如下
inline void NTT(LL *a,int n,int pd) {
for(int i=0;i<n;i++) if(i<rev[i]) swap(a[i],a[rev[i]]);
LL w,o,x,y;
for(int mid=1;mid<n;mid<<=1) {
w=Power(114514,(P-1)/(mid<<1));
for(int i=0;i<n;i+=(mid<<1)) {
o=1;
for(int j=0;j<mid;j++,o=o*w%P) {
x=a[i+j]; y=o*a[i+j+mid]%P;
a[i+j]=(x+y)%P; a[i+j+mid]=(x-y+P)%P;
}
}
}
if(pd==-1) {
reverse(a+1,a+n); LL s=Power(n,P-2);
for(int i=0;i<n;i++) a[i]=a[i]*s%P;
}
}
导数
定义:函数在某一点的导数就是该函数所代表的曲线在这一点上的切线斜率
常用导数
泰勒展开式
牛顿迭代
已知
考虑倍增,假设我们现在已经求出了
易知,肯定满足有
则两多项式相减后在模
将
倍增处理就完事了
多项式求逆
给定
考虑倍增,假设我们已经求出
首先有
那么
在等式两边同时乘上
因为
inline void Inv(int n,LL *G,LL *f) {
if(n==1) { f[0]=Power(G[0],P-2); return ; }
Inv((n+1)>>1,G,f);
t=1; bit=0;
while(t<(n<<1)) t<<=1; while((1<<bit)<t) bit++;
for(int i=1;i<t;i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<bit-1);
for(int i=0;i<n;i++) g[i]=G[i];
for(int i=n;i<t;i++) g[i]=0;
FFT(f,t,1); FFT(g,t,1);
for(int i=0;i<t;i++) f[i]=f[i]*(2LL-f[i]*g[i]%P+P)%P;
FFT(f,t,-1);
for(int i=n;i<t;i++) f[i]=0;
}
多项式除法
给定多项式
令多项式最高次幂指数为
可以发现一个性质:
由于
多项式
给定
两边同时求导
多项式
给定
两边同时取
令函数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现