1. 程式人生 > >【Java】【NTT】Java NTT 模板

【Java】【NTT】Java NTT 模板

模數mod=998244353

import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;
import java.io.StringReader;

public class Main
{
    public static void main(String[] args)throws IOException
    {
        Input in=new Input(new BufferedReader(new InputStreamReader(System.in)));
        	PrintWriter out = new PrintWriter(System.out);
        Poly ans=new Poly();
        ans.run(in,out);
        out.close();
    }

    static class Poly
    {
        public static final long mod=998244353;
        public static final long inv2=499122177;
        public static final long g=3;
        static int[] rev=new int[8000000];
        static int l,tt;
        static long inv;
        
        public void run(Input in,PrintWriter out)throws IOException
        {
            int n,m;
            n=in.nextInt();
            m=in.nextInt();
            init(n+m);
            long a[]=new long[l],b[]=new long[l];
            for(int i=0;i<=n;++i)a[i]=in.nextInt();
            for(int i=0;i<=m;++i)b[i]=in.nextInt();
            a=ntt(a,1);
            b=ntt(b,1);
            for(int i=0;i<l;++i)a[i]=a[i]*b[i];
            a=ntt(a,-1);
            for(int i=0;i<=n+m;++i)out.print(a[i]+" ");
        }
        
        private long qpow(long a,long b)
        {
            long res=1;
            while(b!=0)
            {
                if((b&1)==1)res=res*a%mod;
                a=a*a%mod;
                b>>=1;
            }
            return res;
        }
        
        private void init(int n)
        {
            l=1;
            tt=0;
            while(l<=n)
            {
                l<<=1;
                ++tt;
            }
        }
        
        private long[] ntt(long a[],int dft)
        {
            for(int i=0;i<l;++i)
            {
                rev[i]=(rev[i>>1]>>1)|((i&1)<<(tt-1));
                if(i<rev[i])
                    {long t=a[i];a[i]=a[rev[i]];a[rev[i]]=t;}
            }
            for(int mid=1;mid<l;mid<<=1)
            {
                long nw=qpow(g,(mod-1)/(mid<<1));
                if(dft==-1)nw=qpow(nw,mod-2);
                for(int r=mid<<1,i=0;i<l;i+=r)
                {
                    long w=1;
                    for(int j=0;j<mid;++j)
                    {
                        long x=a[i+j],y=w*a[i+mid+j]%mod;
                        a[i+j]=(x+y)%mod;
                        a[i+mid+j]=(x-y+mod)%mod;
                        w=w*nw%mod;
                    }
                }
            }
            if(dft==-1)
            {
            	inv=qpow(l,mod-2);
                for(int i=0;i<l;++i)
                    a[i]=a[i]*inv%mod;
            }
            return a;
        }
    }

    static class Input
    {
        BufferedReader in;
        StringBuilder sb = new StringBuilder();
        public Input(BufferedReader in){this.in = in;}
        public Input(String s){this.in = new BufferedReader(new StringReader(s));}
        public String next()throws IOException
        {sb.setLength(0);while (true){int c=in.read();if(" \n\r\t".indexOf(c)==-1){sb.append((char)c);break;}}
        while (true){int c=in.read();if(c==-1||" \n\r\t".indexOf(c)!=-1)break;sb.append((char)c);}return sb.toString();}
        public int nextInt()throws IOException{return Integer.parseInt(next());}
    }
}