NTT模板

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define x first
#define y second
#define int long long
#define LL long long
const int N=1e6+100000,mod=998244353,INF=1e9+1,M=(1<<21)+10,g=3;

typedef pair<int,int> PII;  

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

int a[N*2],b[N*2],rev[N*2],bit=0,len=1;
int n,m;

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;
            }
        }
    }
}

void slove(){
    cin>>n>>m;
    for(int i=0;i<=n;i++)cin>>a[i];
    for(int i=0;i<=m;i++)cin>>b[i];
    
    bit=0,len=1;
    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++) a[i]=a[i]*inv%mod;
    for(int i=0;i<=n+m;i++) cout<<a[i]<<" ";
	cout<<endl; 
    
	for(int i=0;i<=len;i++) a[i]=b[i]=rev[i]=0;//多测需要清空的 
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
    int T=1;
    while(T--) slove();
}
posted @ 2025-03-11 13:15  MENDAXZ  阅读(31)  评论(0)    收藏  举报