NTT 模板

其实和 \(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;
}

原文地址:https://www.cnblogs.com/BakaCirno/p/11764238.html

时间: 2024-08-01 06:12:01

NTT 模板的相关文章

多项式FFT/NTT模板(含乘法/逆元/log/exp/求导/积分/快速幂)

自己整理出来的模板 存在的问题: 1.多项式求逆常数过大(尤其是浮点数FFT) 2.log只支持f[0]=1的情况,exp只支持f[0]=0的情况 有待进一步修改和完善 FFT: 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef double db; 5 const db pi=acos(-1); 6 const int N=4e5+10,M=1e6+10,mod=9982443

FFT&amp;NTT模板

博主菜鸡,只会背模板,根本解释不来嘤嘤嘤~ FFT: #include<bits/stdc++.h> #define IL inline #define LF double using namespace std; const int N=5e6+5; const LF Pi=acos(-1.0); struct com{ LF x,y; com(LF xx=0,LF yy=0){x=xx,y=yy;} com operator+(const com &a) const{return

NTT模板

const int G=3; ll c[maxn],d[maxn],tmp[maxn],wn[maxn]; void getwn(int len) { wn[0]=1; wn[1]=qpow(G,(mod-1)/len); int i; rep(i,2,len) wn[i]=wn[i-1]*wn[1]%mod; } void NTT(ll *a,int len,int on){ int i; ll ni=qpow(len,mod-2); rep(i,0,len-1){ int p=0; doub

快速数论变换NTT模板

51nod 1348 乘积之和 #include <cmath> #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <queue> #include <map> #include <bitset> #include <set>

分治FFT/NTT 模板

题目要我们求$f[i]=\sum\limits_{j=1}^{i}f[i-j]g[j]\;mod\;998244353$ 直接上$NTT$肯定是不行的,我们不能利用尚未求得的项卷积 所以要用$CDQ$分治,先递归$[l,mid]$,然后处理$[l,mid]$对$[mid+1,r]$的影响,再递归$[mid+1,r]$ 当我们处理$[l,mid]$对$[mid+1,r]$的影响时,$f[i](i\in [l,mid])$的是已经求完的,所以能用$NTT$卷积 细节比较多,注意不要让$f[i](i\

三模数NTT模板

求两个多项式的卷积对任意数p取模 两个好记的FNT模数: 5*2^25+1 7*2^26+1 原根都为3 1 //Achen 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cstdlib> 6 #include<vector> 7 #include<cstdio> 8 #include<queue> 9 #include&

[hdu1402]A * B Problem Plus(NTT)

解题关键:NTT模板 #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; const int N=50010; typedef long long ll; ll G=3,P=469762049,a[3*N],b[3*N],wn[25

多项式模板整理

多项式乘法 FFT模板 时间复杂度\(O(n\log n)\). 模板: void FFT(Z *a,int x,int K){ static int rev[N],lst; int n=(1<<x); if(n!=lst){ for(int i=0;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<x-1); lst=n; } for(int i=0;i<n;i++)if(i<rev[i])swap(a[

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

我这种数学一窍不通的菜鸡终于开始学多项式全家桶了-- 必须要会的前置技能:FFT(不会?戳我:[知识总结]快速傅里叶变换(FFT)) 一.NTT 跟FFT功能差不多,只是把复数域变成了模域(计算复数系数多项式相乘变成计算在模意义下整数系数多项式相乘).你看FFT里的单位圆是循环的,模一个质数也是循环的嘛qwq.\(n\)次单位根\(w_n\)怎么搞?看这里:[BZOJ3328]PYXFIB(数学)(内含相关证明.只看与原根和单位根相关的内容即可.) 注意裸的NTT要求模数\(p\)存在原根并且\