NTT学习笔记

前言

在看本文之前,需要确保您已经会了FFT(总结在此)并且对于数学的掌握十分的好!

优化

我们考虑一下为什么FFT特别的慢,但是怎么优化呢?

FFT慢的原因是:用了许多的实数导致运算复杂,而且容易出现精度问题,所以怎么解决?

发现一个神奇的东西:

\((W_n)^n=1,(W_n)^{n/2}=-1\)

有了这个不就是和原根很相同吗?

下面有高能预警:
引用yyb的话语:(主要是我自己说不清楚qwq)

假设p的原根是g
再膜p意义下:
\(g^{\phi(p)}=1->g^{\phi(p)/2}=\sqrt{1}\)
因为原根不存在一个比\(\phi(p)\)小的数使得\(g^k=1\)
所以\(g^{\phi(p)/2}=−1\)
我们发现上面的性质也可以满足
所以,把n次单位复根可以替换成原根的\(\phi(p)/(2^n)\)来做
这样就解决了小数精度的问题


但是非常遗憾的是NTT没有什么需要补充的,所以到此结束了qwq.


代码

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
#define ll long long
#define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
inline int gi(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return f*sum;
}
const int P=998244353,G=3,N=5000010;
int f[N],g[N],limit,r[N],n,m;
int Pow(int a,int b){
    int  ret=1;
    while(b){
        if(b&1)ret=(1ll*ret*a)%P;
        a=(1ll*a*a)%P;b>>=1;
    }
    return ret%P;
}
void ntt(int*A,int flag){
    for(int i=0;i<limit;i++)if(i<r[i])swap(A[i],A[r[i]]);
    for(int mid=1;mid<limit;mid<<=1){
        int root=Pow(G,(P-1)/(mid<<1));
        for(int R=mid<<1,j=0;j<limit;j+=R){
            int w=1;
            for(int k=0;k<mid;k++,w=1ll*w*root%P){
                int x=A[j+k],y=1ll*w*A[mid+j+k]%P;
                A[j+k]=(x+y)%P;A[mid+j+k]=(x-y+P)%P;
            }
        }
    }
    if(flag==-1)reverse(&A[1],&A[limit]);
}
int main(){
    n=gi();m=gi();
    for(int i=0;i<=n;i++)f[i]=gi();
    for(int i=0;i<=m;i++)g[i]=gi();
    limit=1;int l=0;
    while(limit<=(n+m))limit<<=1,l++;
    for(int i=0;i<limit;i++)
        r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
    ntt(f,1);ntt(g,1);
    for(int i=0;i<limit;i++)f[i]=1ll*f[i]*g[i]%P;
    ntt(f,-1);
    int inv=Pow(limit,P-2);
    for(int i=0;i<limit;i++)f[i]=1ll*f[i]*inv%P;
    for(int i=0;i<=n+m;i++)printf("%d ",f[i]);
    puts("");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/MLEAutomaton/p/10309720.html
NTT