【文文殿下】快速数论变换(NTT)学习笔记

关于NTT 和FFT 一模一样(躺倒

模板程序

#include<cstdio>
#include<cmath>
#include<algorithm>
typedef long long ll;
const int g(3),p(998244353);
inline int exp(int a,int b,int p) {
	if(b<0) b+=p-1;
	ll base = a;
	ll ans = 1;
	while(b) {
		if(b&1) {
			ans=ans*base%p;
		}
		base=base*base%p;
		b>>=1;
	}
	return (int)ans;
}

void dft(int *a,int n,int x)
{
    for (int i=1,j=n/2;i<n-1;i++)
    {
        if (i<j) std::swap(a[i],a[j]);
        int p=n/2;
        while (j>=p) j-=p,p>>=1;
        j+=p;
    }
    for (int j=2;j<=n;j*=2)
    {
        int wn=exp(g,1LL*(p-1)/j*x,p);
        for (int i=0;i<n;i+=j)
        {
            int w=1;
            for (int k=i;k<i+j/2;k++)
            {
                int u=a[k],t=1LL*a[k+j/2]*w%p;
                a[k]=(u+t)%p;a[k+j/2]=(u-t+p)%p;
                w=1LL*w*wn%p;
            }
        }
    }
    if (x==-1)
    {
        int inv=exp(n,p-2,p);
        for (int i=0;i<n;i++) a[i]=1LL*a[i]*inv%p;
    }
}
void mult(int *a,int *b,int n)
{
    dft(a,n,1);dft(b,n,1);
    for (int i=0;i<n;i++) a[i]=1LL*a[i]*b[i]%p;
    dft(a,n,-1);
}
int n,m;
const int maxn = 1e6;
int a[maxn<<2],b[maxn<<2];
int main()
{
	scanf("%d%d",&n,&m);
	int limit = 1;
	while(limit<=n+m+1) limit<<=1;
	for(int i = 0;i<=n;++i) scanf("%d",&a[i]);
	for(int i = 0;i<=m;++i) scanf("%d",&b[i]);
	mult(a,b,limit);
	for(int i = 0;i<n+m+1;++i) {
		printf("%d ",(a[i]%p)%p);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/Syameimaru/p/9964776.html