\(FFT\)
简单来说做的就是多项式乘法,能够将多项式乘法的时间复杂度从 \(o(n^2)\) 优化至 \(o(nlogn)\) 。其思想就是将多项式由系数表示法转化为点值表示法,快速求出新多项式的点值表示,再将其转化为系数表示法。
将多项式按照奇偶项分开
每次选择单位圆上的点所表示的复数带入计算即可。
可以发现一个规律:系数不断递归下去最终的位置将会是其二进制翻转后所表示的数。
代码模板如下:
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;
}
}
}
}
\(NTT\)
整数 \(FFT\) ,就是用原根代替单位根,其余同 \(FFT\) 。
\(3、114514\) 为模数 \(998244353\) 的原根。
找原根的方法:
将模数 \(P-1\) 分解质因数为 \(\prod_{i=1}^mp_i^{c_i}\) ,则 \(g\) 为 \(P\) 的原根当且仅当 \(\forall i \in [1,m]\) 都满足 \(g^{\frac{P-1}{p_i}}\not \equiv 1 (\mod P)\) 。
模板如下
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;
}
}
导数
定义:函数在某一点的导数就是该函数所代表的曲线在这一点上的切线斜率 \(by \quad Baidu\)
常用导数
泰勒展开式
牛顿迭代
已知 \(G(x)\) ,求 \(F(x)\) 满足
考虑倍增,假设我们现在已经求出了 \(G(F_n(x)) \equiv 0\quad (\mod x^n)\) ,我们要凭借此推出 \(G(F_{2n}(x))\equiv 0\quad (\mod x^{2n})\) 。
易知,肯定满足有
则两多项式相减后在模 \(x^n\) 的意义下最低非零项为 \(a_nx^n\) 。所以
将 \(G(F_{2n}(x))\) 在 \(F_n(x)\) 处泰勒展开
倍增处理就完事了
多项式求逆
给定 \(G(x)\) ,求 \(F(x)\) 满足 \(F(x)G(x) \equiv 1(\mod x^n)\)
考虑倍增,假设我们已经求出 \(F_n(x)G(x) \equiv 1(\mod x^n)\) ,现在我们要求出 \(F_{2n}(x)G(x) \equiv 1(\mod x^{2n})\) 。
首先有
那么
在等式两边同时乘上 \(G(x)\)
因为 \(F_{2n}(x)G(x) \equiv 1(\mod x^{2n})\)
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;
}
多项式除法
给定多项式 \(A(x)\) 、\(B(x)\) ,求 \(D(x)\) 、\(R(x)\) ,满足 \(A(x)=B(x)D(x)+R(x)\)
令多项式最高次幂指数为 \(deg\) 。不妨设 \(deg(A(x))=n, deg(B(x))=m, deg(D(x))=n-m,deg(R(x))=m-1\)
可以发现一个性质: \(x^{deg(F(x))}F(\frac{1}{x})\) 就是将 \(F(x)\) 系数翻转所得的多项式,记为 \(F^R(x)\)
由于 \(deg(D(x))=n-m\leq n-m+1\) ,故此时求出来的 \(D(x)\) 是真实的。
多项式 \(\ln\)
给定 \(G(x)\) 求 \(F(x)\) 满足 \(F(x)\equiv \ln G(x) \quad(\mod x^n)\)
两边同时求导
\(F(x)\) 常数项为 \(0\) ,\(G(x)\) 常数项为 \(1\) 。
多项式 \(exp\)
给定 \(G(x)\) ,求 \(F(x)\) 满足 \(F(x)\equiv e^{G(x)} \quad (\mod x^n)\)
两边同时取 \(\ln\)
令函数 \(P(X)=\ln X-G(x)\) ,在这里我们将 \(G(x)\) 视为一个常函数。套牛顿迭代的式子。
\(F(x)\) 的常数项为 \(1\) ,\(G(x)\) 的常数项为 \(0\) 。
原文地址:http://www.cnblogs.com/oscaryangzj/p/16845827.html