首页 > 其他分享 >多项式学习笔记

多项式学习笔记

时间:2024-04-21 17:44:18浏览次数:23  
标签:frac int 多项式 sum 手环 笔记 学习 omega

1. 快速傅里叶变换(FFT)

1.1. 定义

傅里叶变换(法语:Transformation de Fourier,英语:Fourier transform,缩写:FT)是一种线性变换,通常定义为一种积分变换。其基本思想是一个函数可以用(可数或不可数,可数的情况对应于傅里叶级数)无穷多个周期函数的线性组合来逼近,从而这些组合系数在保有原函数的几乎全部信息的同时,还直接地反映了该函数的“频域特征”。 ——维基百科

呃,这个定义在 OI 中用不到。OI 中的 FFT 其实是这样定义的:

设 \(\{x_n\}_{n=0}^{N-1}\) 是某一满足有限性条件的序列,它的离散傅里叶变换(DFT)为:

\[X_k=\sum_{n=0}^{N-1}x_n\mathrm{e}^{-\mathrm{i}\frac{2\pi}{N}kn} \]

——OI-Wiki

实际上,FFT 可以理解为对于形如 \(F(x)=\sum_{i=0}^n a_ix^i\) 的多项式,快速求 \(F(x)\) 在 \(n\) 次单位根上的 \(n+1\) 个点值 \((\omega_n^i,F(\omega_n^i))\) 。

1.2. 快速傅里叶变换(FFT)

不妨令 \(n=2^a(a\in\N)\) 。如果 \(n\ne 2^a\) ,就可以补0凑成 \(2^a\) 。设 \(G(x)=\sum_{i=0}^{n/2}a_{2i}x^{2i}\) , \(H(x)=\sum_{i=0}^{n/2}a_{2i+1}x^{2i}\) ,根据单位根的周期性,存在

\[F(\omega_n^i)= G(\omega_n^{2i \mod n})+\omega_n^iH(\omega_n^{2i \mod n})=G(\omega_{n/2}^{i \mod \frac{n}{2}})+\omega_n^iH(\omega_{n/2}^{i\mod \frac{n}{2}}) \]

当 \(i\in [0,\frac{n}{2}-1]\) 时,满足

\[F(\omega_n^{i})=G(\omega_{n/2}^{i})+\omega_n^iH(\omega_{n/2}^{i})\\ \omega_n^{i+\frac{n}{2}}=-\omega_n^{i}\\ F(\omega_n^{i+\frac{n}{2}})=G(\omega_{n/2}^{i})+\omega_n^{i+\frac{n}{2}}H(\omega_{n/2}^{i})=G(\omega_{n/2}^{i})-\omega_n^{i}H(\omega_{n/2}^{i}) \]

这就可以用分治的方法求 \(F(\omega_n^i)\) 。假设已经递归地求出所有 \(G(\omega_{n/2}^i)\) 和 \(H(\omega_{n/2}^{i})\)(相当于把奇偶次项分开,再对分出来的两个 \(\frac{n}{2}\) 次多项式 FFT),就可以用上面的两个式子求出所有的 \(F(\omega_n^i)\) 。

代码如下:

typedef complex<double> Comp;
void FFT(Comp *f,int n,int rev){
    if(n==1){
        return;
    }else{
        for(int i=0;i<n;i++){
            tmp[i]=f[i];
        }
        for(int i=0;i<n;i++){//分离奇偶次项
            if(i%2){
                f[i/2+n/2]=tmp[i];
            }else{
                f[i/2]=tmp[i];
            }
        }
        Comp *g=f+n/2;
        FFT(f,n/2,rev);FFT(g,n/2,rev);
        Comp cur(1,0),step(cos(2*M_PI/n),sin(2*M_PI*rev/n));
        for(int i=0;i<n/2;i++){
            tmp[i]=f[i]+cur*g[i];
            tmp[i+n/2]=f[i]-cur*g[i];
            cur*=step;
        }
        for(int i=0;i<n;i++){
            f[i]=tmp[i];
        }
    }
}

但是递归常数太大了。可以考虑从下到上“合并”多项式。一个多项式的系数组成的数列在 FFT 中位置关系的变换大概如下:

0 1 2 3 4 5 6 7 =>
0 2 4 6 1 3 5 7 =>
0 4 2 6 1 5 3 7

注意到如果把序号写成二进制,变换后的序号就是变换前的序号翻转过来。因此可以写出如下代码:

void initrev(int lim){//预处理二进制翻转
    for(int i=0;i<lim;i++){
        rev[i]=(rev[i>>1]>>1)|((i&1)*(lim>>1));
    }
}
void FFT(Comp f[],int lim,int opt){
    for(int i=0;i<lim;i++){
        if(rev[i]<i){
            swap(f[rev[i]],f[i]);
        }
    }
    for(int m=2;m<=lim;m<<=1){
        int k=m>>1;
        Comp step(cos(M_PI/k),sin(M_PI*opt/k));
        for(int i=0;i<lim;i+=m){
            Comp cur(1,0);
            for(int j=0;j<k;j++,cur=cur*step){
                Comp tmp=f[i+j+k]*cur;
                f[i+j+k]=f[i+j]-tmp;
                f[i+j]=f[i+j]+tmp;
            }
        }
    }
    if(opt==-1){
        for(int i=0;i<lim;i++){
            f[i]=f[i].real()/lim;
        }
    }
}

这优化被称为“蝶形变换”。

1.3. 快速傅里叶逆变换

以后再写

2. 快速数论变换(NTT)

FFT 利用了单位根的性质,在模意义下有一种叫“原根”的数也具有类似的性质。

2.1. 阶和原根

对于常数 \(a\) ,定义最小的满足 \(a^l\equiv 1 \pmod p\) 的 \(l\) 为 \(a\) 在 \(\bmod p\) 意义下的阶。

若 \(k\) 在 \(\bmod p\) 意义下的阶为 \(\varphi(p)\) ,则称 \(k\) 为 \(p\) 的原根。

设 \(G\) 是 \(p\) 的原根,则 \(G^{\varphi(p)} \equiv 1 \pmod p\) 。即 \(G\) 的幂运算在 \(\bmod p\) 意义下的周期为 \(\varphi(p)\) 。故当 \(x|\varphi(p)\) 时, \(G^{\frac{\varphi(p)}{x}}\) 可以与单位根 \(w_x\) 类比,不妨记 \(w_n=G^{\frac{\varphi(p)}{n}}\) 。

与单位根类似,这里的 \(w\) 也满足 \(w_2\equiv -1 \pmod p\) 。以下是笔者自己瞎胡的伪证:

解方程 \((w_2)^2\equiv G^{\varphi(p)} \pmod p\) 可知 \(w_2\equiv 1 或 -1 \pmod p\)。当 \(w_2=1\) 时存在 \(G^{\frac{\varphi(p)}{2}}\equiv 1 \pmod p\) ,由于 \(\frac{\varphi(p)}{2} < \varphi(p)\) ,可推出 \(G\) 不是 \(p\) 的原根,与假设矛盾,故 \(w_2\equiv -1 \pmod p\) 。

2.2. NTT

考虑对在模 \(p\) 意义下的 \(n\) 次多项式进行与 FFT 类似的变换。

与 FFT 类似 ,NNT 可以求 \(F(x)\) 在 \(\mod p\) 意义下的 \(n+1\) 个点值 \((\omega_n^i,F(\omega_n^i))\) 。仍然令 \(n=2^a(a\in\N)\) ,\(F(x)=\sum_{i=0}^n a_ix^i\), \(G(x)=\sum_{i=0}^{n/2}a_{2i}x^{2i}\) , \(H(x)=\sum_{i=0}^{n/2}a_{2i+1}x^{2i}\) ,设 \(p\) 为质数且 \(p=k2^b+1\) 满足 \(b>a\) (即 \(\varphi(p)=k2^b\) ,这是为了保证 \(w_n\) 一直存在),则有

\[F(\omega_n^{i})\equiv G(\omega_{n/2}^{i})+\omega_n^iH(\omega_{n/2}^{i}) \pmod p\\ \omega_n^{i+\frac{n}{2}}\equiv \omega_n^{i}(\omega_2+1)-\omega_n^{i} \equiv -\omega_n^{i} \pmod p\\ F(\omega_n^{i+\frac{n}{2}})\equiv G(\omega_{n/2}^{i})+\omega_n^{i+\frac{n}{2}}H(\omega_{n/2}^{i})\equiv G(\omega_{n/2}^{i})-\omega_n^{i}H(\omega_{n/2}^{i}) \pmod p \]

分离奇偶项后分治的想法仍然有效。这里直接给出蝶形变换优化的代码:

void initrev(int lim){
    for(int i=0;i<lim;i++){
        rev[i]=(rev[i>>1]>>1)|((i&1)*(lim>>1));
    }
}
void NTT(int f[],int lim,int opt){//当 opt=-1时为逆变换
    for(int i=0;i<lim;i++){
        if(rev[i]<i){
            swap(f[rev[i]],f[i]);
        }
    }
    for(int m=2;m<=lim;m<<=1){
        int k=m>>1;
        int step=ksm(opt==1?G:INV_G,(P-1)/m);
        for(int i=0;i<lim;i+=m){
            int cur=1;
            for(int j=0;j<k;j++,cur=cur*step%P){
                int tmp=f[i+j+k]*cur%P;
                f[i+j+k]=(f[i+j]-tmp+P)%P;
                f[i+j]=(f[i+j]+tmp)%P;
            }
        }
    }
    if(opt==-1){
        int inv=ksm(lim,P-2);
        for(int i=0;i<lim;i++){
            f[i]=f[i]*inv%P;
        }
    }
}

逆变换与 FFT 类似,这里不作赘述。

顺便提一下,\(998244353\) 是质数且 \(998244353=2^{23}\times 7\times 17+1\) ,它的原根是 \(3\) ,因此在可以用 NTT 的题目里经常要求模 \(998244353\) 。

2.3. 任意模数 NTT

NTT 对 \(p\) 有比较严格的限制......

......

以后再写

3. 多项式初等函数

3.1. 多项式卷积

洛谷 P3803

给定一个 \(n\) 次多项式 \(F(x)\),和一个 \(m\) 次多项式 \(G(x)\)。请求出 \(F(x)\) 和 \(G(x)\) 的卷积。

多项式卷积其实就是多项式乘法。多项式 \(H(x)\) 为 \(F(x)\) 和 \(G(x)\) 的卷积时,\(H(x)=F(x)G(x)\) 。例如,当 \(F(x)=1+x\) , \(G(x)=1+x+x^2\) 时 \(H(x)=F(x)G(x)=(1+x)(1+x+x^2)=1+2x+2x^2+x^3\) 。

用 FFT 在单位根处插值后,把点值乘起来就是答案多项式的点值表示,再逆变换把点值表示转换成系数表示就行了。

记多项式 \(F(x)\) 的 \(k\) 次项系数为 \([x^k]F(x)\)。可知 \(H(x)=F(x)*G(x)=(\sum_{i=0}^{n}[x^i]F(x)*x_i)*(\sum_{i=0}^{m}[x^i]G(x)*x_i)=\sum_{i=0}^{n+m}(\sum_{j=0}^{i}[x^j]F(x)*[x^{i-j}]G(x))x_i\),即 \([x_i]H(x)=\sum_{j=0}^{i}[x^j]F(x)*[x^{i-j}]G(x)\) 。

洛谷 P3723

我的室友最近喜欢上了一个可爱的小女生。马上就要到她的生日了,他决定买一对情侣手环,一个留给自己,一个送给她。每个手环上各有 \(n\) 个装饰物,并且每个装饰物都有一定的亮度。

但是在她生日的前一天,我的室友突然发现他好像拿错了一个手环,而且已经没时间去更换它了!他只能使用一种特殊的方法,将其中一个手环中所有装饰物的亮度增加一个相同的非负整数 \(c\)。并且由于这个手环是一个圆,可以以任意的角度旋转它,但是由于上面装饰物的方向是固定的,所以手环不能翻转。需要在经过亮度改造和旋转之后,使得两个手环的差异值最小。

在将两个手环旋转且装饰物对齐了之后,从对齐的某个位置开始逆时针方向对装饰物编号 \(1 \sim n\),其中 \(n\) 为每个手环的装饰物个数, 第 \(1\) 个手环的 \(i\) 号位置装饰物亮度为 \(x_i\),第 \(2\) 个手环的 \(i\) 号位置装饰物亮度为 \(y_i\),两个手环之间的差异值为(参见输入输出样例和样例解释):

\[\sum_{i=1}^{n} (x_i-y_i)^2 \]

麻烦你帮他计算一下,进行调整(亮度改造和旋转),使得两个手环之间的差异值最小,这个最小值是多少呢?

记旋转前两个手环在位置 \(i\) 处的装饰物亮度为 \(a_i\) 和 \(b_i\) ,为了方便不妨假设 \(a_{i+n}=a_i\)。设旋转第一个手环,旋转后 \(1\) 号装饰物对应 \(1+d\) 号装饰物,第一个手环整体加亮 \(c\),不难得出差异值为 \(\sum_{i=1}^n (a_{i+d}+c-b_{i})^2=(\sum_{i=1}^n a_i^2 + \sum_{i=1}^n b_i^2)+(nc^2+2c\sum_{i=1}^na_i-2c\sum_{i=1}^nb_i)-2\sum_{i=1}^na_{i+d}b_i\) 。发现拆开后的第一部分是常数,第二部分是关于 \(c\) 的二次函数,这两部分都容易处理。第三部分是关于 \(d\) 的式子,如果用 \(a^{\prime}_{n-i+1}=a_{i}\) 做代换可以得到 \(\sum_{i=1}^na_{n-i-d+1}^{\prime}b_i\) ,发现这长得特别像上文提到的卷积系数的形式。于是可以考虑进一步假设 \(i>n\) 或 \(i<1\) 时 \(b_i=0\) ,令 \(m=n-d>n\) ,进一步变形得到 \(\sum_{i=1}^{m}a_{m-i}^{\prime}b_i\) ,这就和卷积系数一模一样了。因此,把 \(a^{\prime}\) 和 \(b\) 看作多项式 \(F(x)\) 和 \(G(x)\) 的系数,再算出它们卷积后的多项式所有的系数,就得到了所有可能的 \(\sum_{i=1}^na_{i+d}b_i\) 。取 \(min\) 值即可。

事实上,利用 FFT 进行的快速多项式乘法经常用来快速求值可化为卷积系数形式的式子。

3.2. 多项式乘法逆

洛谷 P4238

给定一个多项式 \(F(x)\) ,请求出一个多项式 \(G(x)\), 满足 \(F(x) * G(x) \equiv 1 \pmod{x^n}\)。系数对 \(998244353\) 取模。

标签:frac,int,多项式,sum,手环,笔记,学习,omega
From: https://www.cnblogs.com/ztxcsl/p/18133753

相关文章

  • Google XTS测试学习
    XTS是一个统称,包含VTS、CTS、GTS,如果是TV类型产品,还要做netflix认证,简称NTS,其余TS含义如下: CTS测试简介Android的CTS测试,意为兼容性测试;只有通过CTS测试的设备才有可能获得Android的商标和享受AndroidMarket的权限AndroidCTS通过运行和安装一系列dex和APK文件,通过模......
  • 李沐动手学习深度学习 锚框部分代码解析
    这里只是对代码的解析,我在写这个解析的时候并没有看后面的内容,只能大概猜一下可能是要干嘛的首先是import相关工具,这里使用pytorch%matplotlibinlineimporttorchfromd2limporttorchasd2ltorch.set_printoptions(2)#精简输出精度1.生成锚框接下来是第一个难点,这......
  • JAVA学习第一次Blog
    前段时间老师在PTA上发布了三次大作业,这几次大作业的难度都比较高,对我来说除了前面的题目,最后的大分数压轴题我每次都做不出来。这与上个学期学的C语言作业难度简直不是一个等级的,不过JAVA老师也在上课期间一直强调,“我们JAVA课程一定要做出改变,不能说怕学生挂科就把难度设置的很......
  • linux shell 编程学习总结
    1文件和数组1.1读文件并将文件内容保存到数组,遍历数组src.f文件内容./src/xxx_1.md./src/xxx_2.md./src/xxx_3.md./src/xxx_4.md./src/xxx_5.mdrun.sh#!/bin/bash###readflisttoarraysrc_array=()whilereadline;dosrc_array+=("$line")done<$1##......
  • 《Effective C++》读书笔记
    《EffectiveC++》读书笔记之前看过一遍,不过草草了事。近日看了《深度探索C++对象模型》,想起《EffectiveC++》中的内容已经有些忘记了,所以重新温习一下。这篇笔记只挑选书中的一些重要内容进行记录。条款07:为多态基类声明virtual析构函数这一个条款几乎是面试中的高频问题,只需......
  • FFmpeg开发笔记(十六)Linux交叉编译Android的OpenSSL库
    ​《FFmpeg开发实战:从零基础到短视频上线》一书的例程主要测试本地的音视频文件,当然为了安全起见,很多网络视频都采用了https地址。FFmpeg若要访问https视频,就必须集成第三方的openssl库,但编译FFmpeg时却默认关闭了openssl。为了让App能够播放采用https的在线视频,需要编译安装并启......
  • 离散数学笔记——集合
    离散数学笔记——集合集合的概念集合是由一些确定的元素所组成的整体,其中的元素可以是任何事物定义:A={a1,a2,a3,...,an}表示集合的名称,{}表示集合的符号。a1,a2,a3,...an表示集合中的元素x∈A表示元素x属于集合A集合的特点集合没有重复元素集合......
  • 抽象代数复习笔记
    谨以此文,悼念我炸裂的危寄分欸二期中考试。下次不仅要带一个脑子做题,还得带一个脑子盯着它做题,不然第一个脑子容易跑偏刹不住车。得去黑市看一眼最近脑子市价如何,如果太贵还得卖点东西凑一凑。1.群1.1群的定义群,是一个由一个集合\(G\)和一种\(G\)上的二元运算\(\times\)......
  • 【生物笔记】遗传
    内容来自教辅主编王友祺。基本定义与概念基因基因概念等位基因:位于同源染色体上的同一位置,控制同一对相对性状的基因。非等位基因:(1)同源染色体上不同位置控制不同相对性状的基因。(连锁)(2)非同源染色体上的基因。(自由组合)复等位基因:控制同一对相对性状的多种基因......
  • 吉他乐理学习
    和声是多个和弦构成的集合一、99%的和弦如下图所示(P143)二、大(明亮)三和弦和小(忧伤)三和弦以及增减(增减是指根音和五音是增减五度的关系)三和弦(P145)  三、三和弦的第一转位和第二转位(P146) ......