码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】NTT

时间:2019-05-05 01:33:23      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:因此   策略   c++   math   ace   分治   功能   ret   swap   

NTT(快速数论变换)是一种更高效的计算多项式卷积的算法,具体优势体现在不涉及浮点数之间的运算,依靠取模操作完成与 FFT 相同的功能。
NTT 利用了数论中原根和复数中单位根的四点相同的性质来进行对单位根运算的替代。
具体来说,FFT 之所以具有十分优秀的复杂度,归根结底是由于单位根具备以下四点性质。

  1. \(\omega_{n}^i\) 之间互不相同,这里保证的是点值选取的独立性。
  2. 蝴蝶操作性质1,\(\omega_{2n}^{2k}=\omega_{n}^k\),这里保证了分治策略的可行性。
  3. 蝴蝶操作性质2,\(\omega_{n}^{k+{n\over 2}}=-\omega_{n}^k\),这里保证了分治策略的可行性。
  4. \(\sum_{i=0}^{n-1}\omega_n^{ki}=0\),这里保证了离散傅里叶逆变换的成立。

对于 NTT 来说,可以发现数论中的原根同样满足以上四点性质,因此可以使用其替代单位根进行在模 \(P\) 意义下的运算。
具体模数取作 \(998244353=7*17*2^{23}+1\),即:支持多项式项数在 \(1e6\) 级别的卷积计算。
另外,在这个模数下,\(3\) 是其中的一个原根,\(332748118\)\(3\) 的逆元。

代码如下

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL fpow(LL a,LL b,LL mod){LL ret=1%mod;for(;b;b>>=1,a=a*a%mod)if(b&1)ret=ret*a%mod;return ret;}
const int mod=998244353,g=3,ig=332748118;
const int maxn=3e6+10;

int n,m;
int tot=1,bit,rev[maxn];
LL a[maxn],b[maxn];

void NTT(LL *t,int type){
    for(int i=0;i<tot;i++)if(i<rev[i])swap(t[i],t[rev[i]]);
    for(int mid=1;mid<tot;mid<<=1){
        LL wn=fpow(type==1?g:ig,(mod-1)/(mid<<1),mod);
        for(int j=0;j<tot;j+=(mid<<1)){
            LL w=1;
            for(int k=0;k<mid;k++,w=w*wn%mod){
                LL x=t[j+k],y=w*t[j+mid+k]%mod;
                t[j+k]=(x+y)%mod,t[j+mid+k]=(x-y+mod)%mod;
            }
        }
    }
}

void read_and_parse(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<=n;i++)scanf("%d",&a[i]);
    for(int i=0;i<=m;i++)scanf("%d",&b[i]);
    while(tot<=n+m)tot<<=1,++bit;
    for(int i=0;i<tot;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1));
}
void solve(){
    NTT(a,1),NTT(b,1);
    for(int i=0;i<tot;i++)a[i]=a[i]*b[i]%mod;
    NTT(a,-1);
    LL inv=fpow(tot,mod-2,mod);
    for(int i=0;i<=n+m;i++)printf("%lld ",a[i]*inv%mod);
}
int main(){
    read_and_parse();
    solve();
    return 0;   
}

【模板】NTT

标签:因此   策略   c++   math   ace   分治   功能   ret   swap   

原文地址:https://www.cnblogs.com/wzj-xhjbk/p/10810476.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!