NTT模版

emm 这好像是我第一次放模版。。
但是很懒,不想放头文件,反正函数部分对了就好吧。。。

const int Q=500000,MOD=998244353;
inline int add(int a,int b)
{a+=b;return a<MOD?a:a-MOD;}
inline int sub(int a,int b)
{a-=b;return a<0?a+MOD:a;}
inline int ch(int a,int b)
{return 1LL*a*b%MOD;}
inline int ksm(int a,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1)ans=ch(ans,a);
        b>>=1,a=ch(a,a);
    }
    return ans;
}
int w[Q];
void NTT(int a[],int n,int f)
{
    register int i,j,k,m,cnt=1;
    for(i=j=0;i<n;i++)
    {
        if(i<j)swap(a[i],a[j]);
        for(k=n>>1;(j^=k)<k;k>>=1);
    }
    w[0]=1;
    for(m=1;m<n;m<<=1,++cnt){
        int _now=ksm(3,(f*((MOD-1)>>cnt)+MOD-1)%(MOD-1));
        for(i=1;i<m;i++)w[i]=ch(w[i-1],_now);
        for(i=0;i<n;i+=(m<<1))
            for(j=0;j<m;j++){
                int p=a[i+j],q=ch(a[i+j+m],w[j]);
                a[i+j]=add(p,q),a[i+j+m]=sub(p,q);
            }
    }
    if(f<0){
        int n_ni=ksm(n,MOD-2);
        for(i=0;i<n;i++)a[i]=ch(a[i],n_ni);
    }
}
int t[Q];
void Mul(int a[],int b[],int n)
{
    register int i;
    for(i=0;i<n;i++)t[i]=b[i];
    NTT(a,n,1),NTT(t,n,1);
    for(i=0;i<n;i++)a[i]=ch(a[i],t[i]);
    NTT(a,n,-1);
}

猜你喜欢

转载自blog.csdn.net/includelhc/article/details/80206554
NTT