NTT简单总结

Posted evan704

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NTT简单总结相关的知识,希望对你有一定的参考价值。

NTT简单总结

NTT是一个玄学的东西,它通过数论达到和FFT一样的效果(甚至还要快得多)。

NTT的原理其实是将FFT的$w^k_n$通过另外一个东西代替,从而将FFT中极其之慢的(而且精度爆炸的)浮点数运算更改为整数运算。

在讲NTT之前,先来了解一下数学方面的内容。

数学部分

若$(a,p)$=1,且$p>1$,对于$a^n\\equiv1(mod p)$最小的$n$称为$a$模$p$的阶,记为$\\delta_p(a)$

原根

设正整数$p$,整数$a$,若$\\delta_p(a)=\\phi(p)$则称$a$是模$p$的一个原根

原根有一些有趣的性质,而且跟我们在FFT中用到的单位根用到的性质一样!别问我怎么证

为了避免吐槽,还是放个大佬证明

技术图片

好的,我们终于将浮点数运算转换到了整数域运算。

所以我们直接将FFT代码中的单位根全部换成原根就阔以了。

(不会FFT的请左转百度或右转我的博客

 代码部分

话说这种算法都应该背模板

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=1e7+5,P=998244353,P1=3,P2=332748118;
int lena,lenb,n=1,lim,r[N];
ll a[N],b[N];
ll rpow(ll x,ll y)//要手打
	ll res=1;
	while(y)
		if(y&1)res=(res*x)%P;
		x=(x*x)%P;
		y>>=1;
	
	return res%P;

inline int read()
    int x=0,f=1;
    char ch=getchar();
    while(ch<‘0‘||ch>‘9‘)
        if(ch==‘-‘)f=-1;
        ch=getchar();
    
    while(ch>=‘0‘&&ch<=‘9‘)
        x=x*10+ch-‘0‘;
        ch=getchar();
    
    return x*f;

void NTT(ll *A,int tp)
    for(int i=0;i<n;i++)if(i<r[i])swap(A[i],A[r[i]]);
    for(int i=1;i<n;i<<=1)
        ll W=rpow(tp?P1:P2,(P-1)/(i<<1));//替换成原根
        for(int j=i<<1,k=0;k<n;k+=j)
            ll w=1;
            for(int l=0;l<i;l++,w=(w*W)%P)//注意模数
                int x=A[k+l],y=w*A[k+i+l]%P;
                A[k+l]=(x+y)%P;
                A[k+i+l]=(x-y+P)%P;
            
        
    

int main()
    lena=read();lenb=read();
    while(n<=lena+lenb)n<<=1,lim++;
    for(int i=0;i<=lena;i++)a[i]=(read()+P)%P;
    for(int i=0;i<=lenb;i++)b[i]=(read()+P)%P;
    for(int i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(lim-1));
    NTT(a,1);
    NTT(b,1);
    for(int i=0;i<=n;i++)a[i]=(a[i]*b[i])%P;
    NTT(a,0);
    ll inv=rpow(n,P-2);
    for(int i=0;i<=lena+lenb;i++)printf("%d ",(a[i]*inv)%P);
 

  

实测洛谷P3803用FFT 3.14s,NTT 1.76s(不吸氧)

技术图片

(上为NTT,下为FFT)

以上是关于NTT简单总结的主要内容,如果未能解决你的问题,请参考以下文章

FFT/NTT基础题总结

FFT NTT 错误总结(持续更新)

知识总结多项式全家桶(NTT加减乘除和求逆)

多项式的基本运算(FFT和NTT)总结

NTT小结及原根求法

基数排序总结