NTT 模板

醉酒当歌 提交于 2019-12-02 20:34:17

其实和 $FFT$ 就是一个模子里刻出来的一样,

$FFT$ 的优化是基于它的单位根

而 $NTT$ 的模数通常有一个原根, 和 $FFT$ 的单位根有类似的性质

还是存个模板

模板题

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 3000010
using namespace std;
typedef long long LL;
const int mod=998244353;
const int g=3;
int n,m,rev[MAXN],bit=0,len=1;
LL a[MAXN],b[MAXN];
int read(){
    int x=0,f=1;char c=getchar();
    while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9') {x=x*10+c-'0';c=getchar();}
    return x*f;
}

LL qpow(LL x,LL k){
    LL res=1;
    while(k){
        if(k&1) res=res*x%mod;
        x=x*x%mod;
        k>>=1;
    }
    return res;
}

void NTT(LL *a,int opt){
    for(int i=0;i<len;i++)
        if(i<rev[i]) swap(a[i],a[rev[i]]);
    for(int mid=1;mid<len;mid<<=1){
        LL tmp=qpow(g,(mod-1)/(mid*2));
        if(opt==-1) tmp=qpow(tmp,mod-2);
        for(int i=0;i<len;i+=mid*2){
            LL w=1;
            for(int j=0;j<mid;j++,w=w*tmp%mod){
                LL x=a[i+j],y=w*a[i+j+mid]%mod;
                a[i+j]=(x+y)%mod,a[i+j+mid]=(x-y+mod)%mod;
            }
        }
    }
}

int main(){
    n=read();m=read();
    for(int i=0;i<=n;i++) a[i]=read();
    for(int i=0;i<=m;i++) b[i]=read();
    while(len<=n+m) len<<=1,bit++;
    for(int i=0;i<len;i++) rev[i]=(rev[i>>1]>>1) | ((i&1)<<(bit-1));
    NTT(a,1);NTT(b,1);
    for(int i=0;i<len;i++) a[i]=a[i]*b[i]%mod;
    NTT(a,-1);
    LL inv=qpow(len,mod-2);
    for(int i=0;i<=n+m;i++) printf("%lld ",a[i]*inv%mod);
    return 0;
}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!