基 础 多 项 式 与 基 础 生 成 函 数

噔 噔 噔。

你说的对,但是确实挺基础的说。

很多东西避开了严谨的描述。

文章内容非常浅(che)显(dan)。

prework

卷积 :\(a,b\)为两个数列,两个数列的卷积 \(c\)\(c_k=\sum\limits_{i=1}^{k} a_{i}b_{k-i}\)

多项式的点值表示:\(n+1\) 个坐标确定一个 \(\le n\) 次的多项式,我们可以用这 \(n+1\) 个坐标表示。

注意到直接用点值表示出来的话,能快速的得到相乘的多项式的点值表示。

我们实际上是计算特殊的点值。

单位根:\(x^n-1 =0\) 我们称 \(x\)\(n\) 次单位根,其中 $n \in \mathbb{C} $。我们设 $ \omega $,根据代数基本定理,它在复数集下显然有 \(n\) 个解。我们分别记最小解为 $ \omega_1,\omega_2,\omega_3 \ldots \omega_n$,实际上就是每个角为 \(\frac{2\pi}{n}\),这个东西定义为 \(\omega_{n} = e^{\frac{2\pi i}{n}}\)

$ \because e^{i x } = \cos x+ i\sin x $(欧拉公式)

\(\therefore \omega_n = \cos \frac{2\pi}{n} + i\sin \frac{2\pi}{n}\)

FFT的推导过程

离散傅里叶变换(DFT)

是长这样的,\(a\)是一个数列,对于 \(0 \le k < n\),我们令

\[ b_k=\sum\limits_{i=0}^{n-1} a_i \omega_n^{ki} \]

我们记 \(b=F(a)\)

离散傅里叶变换的逆变换(IDFT)

顾名思义,直接给出式子

\[ a_k=\frac{1}{n}\sum\limits_{i=0}^{n-1} b_i \omega_n^{-ki}(0 \le k < n) \]

证明有点长,大概就是根据定义去推。

意思就是说如果我们知道单位根的点值,就能推出原多项式的系数了。

循环卷积

\(a,b\) 两个数列,

\(c_k=\sum\limits_{i+j \bmod n=k} a_{i}b_{k-i}\)

我们记作 $ c = a * b$

我们有一个性质 \(F(a*b)=F(a) \times F(b)\)

补充单位根的两个性质

Lemma 1:\(({\omega_{2n}}^k)^2={\omega_{n}}^k\)

Lemma 2:\({\omega_{2n}}^{n+k}={\omega_{2n}}^{-k}\)

你把复平面建立出来证明式容易的。

我们对多项式 \(A(x)\) 开始进行操作,我们记 \(n=2m\)

\[A(x)=\sum\limits_{0\le i < n} a_ix^i = \sum\limits_{0\le i < m} a_{2i}x^{2i} +\sum\limits_{0\le i < m} a_{2i+1}x^{2i+1} \]

\[=\sum\limits_{0\le i < m} a_{2i}x^{2i} +x \sum\limits_{0\le i < m} a_{2i+1}x^{2i} \]

注意到有相同的,这是好事。

那我们定义\(A_0(x)=\sum\limits_{0\le i < m} a_{2i}x^{2i} ,A_1(x)= x\sum\limits_{0\le i < m} a_{2i+1}x^{2i}\)

蝴蝶变换

考虑将前面的东西结合一下?下面还是有 \(0 \le k < m\)

\[A(\omega{_n}^k) = A_0(\omega{_n}^k)+A_1(\omega{_n}^k) \]

\[A(\omega{_n}^k) = A_0(({\omega_{2n}}^k)^2)+A_1(({\omega_{2n}}^k)^2) \]

\[A(\omega{_n}^k) = A_0(({\omega_{n}}^k)^2)+ \omega{_n}^k A_1(({\omega_{n}}^k)^2) \]

\[A(\omega{_n}^k) = A_0({\omega_{m}}^{k})+ \omega{_n}^k A_1({\omega_{m}}^{k}) \]

\[A(\omega{_n}^{m+k}) = A_0(({\omega_{n}}^{m+k})^2)+ \omega{_n}^{m+k} A_1(({\omega_{n}}^{m+k})^2) \]

\[A(\omega{_n}^{m+k}) = A_0({\omega_{m}}^{k})- \omega{_n}^k A_1({\omega_{m}}^{k}) \]

通过蝴蝶操作的过程可以看出,如果我们得到了 \(A_0(x),A_1(x)\)

在点\({\omega_{m}}^0,{\omega_{m}}^1 \ldots {\omega_{m}}^{m-1}\),我们可以在 \(O(n)\) 时间内
计算出 \(A(x)\)\({\omega_{m}}^0,{\omega_{m}}^1 \ldots {\omega_{m}}^{m-1}\),我们可以在 \(O(n)\)处的点值。

而计算 \(A_0,A_1\) 的点值的过程可以递归分治进行。
根据主定理,我们可以在 \(O(n\log n)\) 的时间内求出所要的 \(A(x)\) 的点值表示。

为了快速的进行 IDFT,对比 DFT与 IDFT的表达式,可以发
现我们只需要将FFT过程中用到的 \(\omega_{n}\) 全部替换为 \({\omega_{n}}^{-1}\),最后再乘以 \(\frac{1}{n}\) 即可。

\(rev(x)\) 表示将 \(x\) 的二进制位的顺序反转之后得到的数字,我们每次 将 \(a_i = a_{rev(i)}\) 则每次需要对 \(a\) 进行的蝴蝶操作在 \(a′\) 中变成了对两个相邻的序列的操作。方便多了。我觉得你记忆模板就行

#include<bits/stdc++.h>
using namespace std;
const int N=2e6+6,bmod=1e9+7,INF=2e9;
// 省略了缺省源,想看找我要就行了
struct CP{
    db x,y;
    CP(db X=0.0,db Y=0.0){x=X,y=Y;}
    inline CP operator +(const CP &p){return CP(x+p.x,y+p.y);}
    inline CP operator -(const CP &p){return CP(x-p.x,y-p.y);}
    inline CP operator *(const CP &p){return CP(x*p.x-y*p.y,y*p.x+x*p.y);}
}f[N<<1],g[N<<1];
int rev[N<<1];
int n,m;
const db pi=acos(-1);
void FFT(CP *f,db opt){
    rep(i,0,n-1)  if(i<rev[i])    swap(f[i],f[rev[i]]);
    for(int p=2;p<=n;p<<=1){
        int len=(p>>1);
        CP wd(cos(2*pi/p),sin(2*pi/p)*opt);
        static CP w[N];
        w[0]={1,0};
        rep(i,1,len)    w[i]=w[i-1]*wd;
        for(int k=0;k<n;k+=p){
            rep(l,k,k+len-1){
                CP now=f[l+len]*w[l-k];
                f[l+len]=f[l]-now,f[l]=f[l]+now;
            }
        }
    }
}
int main(){
    cin>>n>>m;
    rep(i,0,n)  cin>>f[i].x;
    rep(i,0,m)  cin>>g[i].x;
    for(m+=n,n=1;n<=m;n<<=1);
    rep(i,0,n)  rev[i]=(rev[i>>1]>>1)|((i&1)?(n>>1):0);
    FFT(f,1);FFT(g,1);
    rep(i,0,n)  f[i]=f[i]*g[i];
    FFT(f,-1);
    rep(i,0,m)  cout<<(int)(fabs(f[i].x)/(n*1.0)+0.5)<<" ";
}

NTT

一些定义

阶:对于正整数 \(m,a\),满足 \(\gcd(a,m)=1\), 使得 \(a^{n} \equiv 1 (\bmod m)\),则最小的正整数 \(n\) 称为 \(a\)\(m\) 的阶,记作\(\delta_{m}(a)\)

原根:如果$\delta_{m}(a) =\varphi(m) $,则 \(a\) 是 m 的一个原根。只有模\(2\)\(4\)\(p^a\)\(2p^a\) 存在原根。

\(m > 1\)\(g\) 为正整数且 \(gcd(g,m) = 1\)。则 \(g\)\(m\) 的原根当且仅当对于任意 \(\varphi(m)\) 的质因子 \(q_i\),有 \(g^{\frac{\varphi(m)}{q_i}} \not\equiv 1 (\bmod \ m)\)

暴力找是对的,量级是 \(O(n^{0.25})\)

这里并没有其他内容,后面再补吧。

假设质数 \(p\) 满足 \(p = r \times 2^x + 1\)\(g\)\(p\) 的原根

使用 $g^{\frac{p-1}{n}} $ 带替之前的 \(\omega\),就是 NTT 了。证明略了。

这里应该有一张原根表。

分治FFT/NTT

分治 + FFT,洛谷板子也差不多,略。

全家桶

你好,这个是不是有点不太基础了。

多项式牛顿迭代

有一多项式\(g(x)\),一形式幂级数\(f(x)\),如果有 \(g(f(x))\equiv 0 (\bmod \ x^{n})\),那我们有

\[ f(x) \equiv f_0(x) - \frac{g(f_0(x))}{g'(f_0(x))}(\bmod \ x^{2^n}) \]

接下来都是默认在模意义下的。

证明需要使用泰勒展开,我们首先有 \(g(f0(x))\equiv 0 (\bmod \ x^{n})\)

\[g(f(x))= \frac{g(f_0(x))}{0!}\times (f(x)-f_0(x))^0 + \frac{g'(f_0(x))}{1!}\times (f(x)-f_0(x))^1+ \frac{g''(f_0(x))}{2!} \times (f(x)-f_0(x))^2 +\dots \]

实际上第三项之后就是 \(0\),所以

\[g(f(x))= g(f_0(x)) + g'(f_0(x))\times (f(x)-f_0(x)) \]

变形可以得到

\[ f(x) = f_0(x) - \frac{g(f_0(x))}{g'(f_0(x))} \]

实际上证明并不重要,接下来才是好玩的。

多项式求逆(乘法逆)

有多项式 \(h(x)\),若\(f(x)h(x) \equiv 1(\bmod \ x^n)\)\(f(x)\)\(h(x)\) 的乘法逆。

设多项式\(G(x)\)\(G(f(x))=\frac{1}{f(x)} -h(x)\)

套公式得$ f(x) = f_0(x) - \frac{G(f_0(x))}{G'(f_0(x))}$,然后 \(f(x) = f_0(x) - \frac{\frac{1}{f_0(x)} -h(x)}{-\frac{1}{{f_{0}(x)}^2}}\)

得到结论 $ f(x) \equiv f_0(x) - {f_0}^2(x)h(x) \ (x \bmod \ x^{2n})$

继续咕咕。

生成函数

咕咕

一些题目

题目先咕咕了,后面来写,可能会重开一篇。

P1919 【模板】高精度乘法 | A*B Problem 升级版

注意到高精度乘法本身就是一个卷积,直接把每一位当系数卷积即可,要处理一下进位。

P3338[ZJOI2014]力

咕咕。

P3723 [AH2017/HNOI2017] 礼物

题目是搞笑的,笔者看错题了,笔者更搞笑。

我们考虑一下增量为 \(\Delta\) 会发生什么。

\(\sum\limits_{i=1}^n=(x_i-y_i+\Delta)^2 = \sum\limits_{i=1}^n({x_i}^2+{y_i}^2-2x_iy_i-2\Delta(x_i-y_i) +\Delta^2)= \sum\limits_{i=1}^n({x_i}^2+{y_i}^2 )-\sum\limits_{i=1}^n2x_iy_i-2\Delta\sum\limits_{i=1}^n(x_i)-\sum\limits_{i=1}^n(y_i)+n\Delta^2\)

枚举 \(\Delta\),只有 \(\sum\limits_{i=1}^n2 x_i y_i\) 不是定值。

考虑怎么求这个东西的最值,如果没有题目上的限制的话是P1966[NOIP2013 提高组] 火柴排队,我们设它旋转了 \(k\) 次 ,第 \(k\) 次的和就是 \(\sum\limits_{i=1}^n2 x_{i+k +[i+k>n] \times -1} y_i\) 确实太不好看了,断环为链,倍长出去就是 \(\sum\limits_{i=1}^n2 x_{i+k } y_i\)

经典Trick,直接翻转 \(x\),得到\(\sum\limits_{i=1}^n2 x_{2n-i-k } y_i\),这个就是卷积啊,答案就在 \(n+1\)\(2n\) 之间的最值。那么就做完了。

posted @ 2025-01-21 20:23  q1uple  阅读(10)  评论(0编辑  收藏  举报
1