NTT学习笔记

本文介绍了NTT(Number Theoretic Transform)与FFT(Fast Fourier Transform)的基本原理及应用。探讨了NTT作为FFT的一种离散化变体,在处理整数运算及避免浮点数精度损失方面的优势。同时给出了NTT的实现代码示例。

前言

KOI里发现一个我连暴力都不会打的题可以NTT水80分
于是我就下定决心学一手NTT,顺便复习FFT
主要都是推多项式啦

一些关于NTT的东西

其实NTT也很简单,和FFT差不多
为什么需要NTT呢,因为FFT带了三角函数和浮点数运算,精度误差有时候会比较大
而且对于取模的时候,需要搞个任意膜(膜myy),精度误差更大
所以就出现了NTT

关联

在FFT中,我们有一个欧拉函数e2πi/ne−2πi/n
我们知道,这个玩意叫n次单位复数根。他有折半,消去引理
如果要在自然界找一个能替代这玩意的东西,相当于这个东西也满足折半,消去引理
幸运的是我们还真的找到了一个(又多了一个要学的算法幸运个啥
在模P意义下,有e2πi/n=gp1/ne−2πi/n=gp−1/n,其中g表示p的原根
什么意思?意思就是,我们把n次单位复数根换成上面的第二个式子,就是NTT了
在逆FFT的情况下,我们要取e1e−1作为底数,那么在NTT中,只需要取g的逆元即可,最后除len的情况也是一样的

LL pow_mod(LL a,int b,LL mod)
{
    LL ans=1LL%mod;
    while(b)
    {
        if(b&1)ans=ans*a%mod;
        a=a*a%mod;b>>=1;
    }
    return ans;
}
void NTT(LL *y,int len,int op)
{
    for(int i=0;i<len;i++)if(i<R[i])swap(y[i],y[R[i]]);
    for(int i=1;i<len;i<<=1)
    {
        LL wn=pow_mod(3,(MOD-1)/(i*2),MOD);if(op==-1)wn=pow_mod(wn,MOD-2,MOD);
        for(int j=0;j<len;j+=(i<<1))
        {
            LL w=1;
            for(int k=0;k<i;k++)
            {
                LL u=y[j+k],v=w*y[j+k+i]%MOD;
                y[j+k]=(u+v)%MOD;
                y[j+k+i]=(u-v+MOD)%MOD;
                w=w*wn%MOD;
            }
        }
    }
    if(op==-1)
    {
        LL inv=pow_mod(len,MOD-2,MOD);
        for(int i=0;i<len;i++)y[i]=y[i]*inv%MOD;
    }
}

NTT+快速幂的模板

原根

如果g是P的原根,就是g^(P-1) = 1 (mod P)当且仅当指数为P-1的时候成立.(这里P是素数).
例如求任何一个质数x的任何一个原根,一般就是枚举2到x-1,并检验。有一个方便的方法就是,求出x-1所有不同的质因子p1,p2…pm,对于任何2<=a<=x-1,判定a是否为x的原根,只需要检验a^((x-1)/p1),a^((x-1)/p2),…a^((x-1)/pm)这m个数中,是否存在一个数mod x为1,若存在,a不是x的原根,否则就是x的原根。

int get_root(int s)
{
    int q[1100]={0};
    for(int i=2;i<s-1;i++)
        if((s-1)%i==0)q[++q[0]]=i;
    for(int i=2;;i++)
    {
        bool bk=true;
        for(int j=1;j<=q[0];j++)
        {
            if(pow_mod(i,q[j],s)==1)bk=false;
            if(bk==false)break;
        }
        if(bk==true)return i;
    }
    return -1;
}

学完了?
真的学完了。。
因为NTT是在FFT上扩展出来的东西
证明与FFT的证明引理类似

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值