ZeroJudge i112 - 三則運算 解題心得( 題目 )

解題概念:大數、NTT

解題方法:

Java參考程式碼(有更好意見可留言於下方,謝謝!):

//Author:En Chi Tsung(欉恩祁)

//Date:2022/05/16

import java.io.*;

import java.math.*;

public class zji212 {

    public static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));

    public static BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(System.out));

    public static int ret,rd;

    public static long floor;

    public static int G=3;

    public static int N=1<<21,P=(479<<21)+1,PP=21;

    public static void main(String[] args) throws Exception{

        String[] in=br.readLine().split(" ");

        long[] a=new long[N];

        long[] b=new long[N];

        long[] c=new long[N];

        final String F=in[0];

        final String S=in[2];

        final String O=in[1];

        if(O.equals("+")) {

            for(int i=F.length()-1,j=0;i>=0;i--,j++) {

                a[j]=F.charAt(i)-'0';

            }

            for(int i=S.length()-1,j=0;i>=0;i--,j++) {

                b[j]=S.charAt(i)-'0';

            }

            final int len=Math.max(F.length(),S.length())+5;

            for(int i=0;i<len;i++) {

                c[i]=a[i]+b[i];

                if(c[i]>=10) {

                    a[i+1]++;

                    c[i]-=10;

                }

            }

            int idx;

            for(idx=len;idx>0;idx--) {

                if(c[idx]!=0)break;

            }

            for(;idx>=0;idx--) {

                bw.write(c[idx]+"");

            }

            bw.flush();

        }

        else if(O.equals("-")){

            for(int i=F.length()-1,j=0;i>=0;i--,j++) {

                a[j]=F.charAt(i)-'0';

            }

            for(int i=S.length()-1,j=0;i>=0;i--,j++) {

                b[j]=S.charAt(i)-'0';

            }

            long dl;

            final int len=F.length();

            for(int i=0;i<len;i++) {

                dl=a[i]-b[i];

                if(dl<0) {

                    a[i+1]--;

                    c[i]=(dl+10)%10;

                }

                else {

                    c[i]=dl;

                }

            }

            int idx;

            for(idx=len;idx>0;idx--) {

                if(c[idx]!=0)break;

            }

            for(;idx>=0;idx--) {

                bw.write(c[idx]+"");

            }

            bw.flush();

        }

        else {

            for(int i=F.length()-1,j=0;i>=0;i--,j++) {

                a[j]=F.charAt(i)-'0';

            }

            for(int i=S.length()-1,j=0;i>=0;i--,j++) {

                b[j]=S.charAt(i)-'0';

            }

            if(F.length()+S.length()<=60000) {

                N=1<<16;

                PP=16;

                P=998244353;

            }

            final long e=fast(N,P-2);

            NTT(a,1,N,PP,P);

            NTT(b,1,N,PP,P);

            for(int i=0;i<N;i++) {

                c[i]=(a[i]*b[i])%P;

            }

            NTT(c,-1,N,PP,P);

            for(int i=0;i<N;i++) {

                c[i]=(c[i]*e)%P;

            }

            for(int i=0;i<N-1;i++) {

                c[i+1]+=c[i]/10;

                c[i]%=10;

            }

            int idx;

            for(idx=N-1;idx>0;idx--) {

                if(c[idx]!=0)break;

            }

            for(;idx>=0;idx--) {

                bw.write(c[idx]+"");

            }

            bw.write("\n");

            bw.flush();

        }

        

    }

    

    

    public static void NTT(long[] in,int inv,final int N,final int PP,final int P) {

        long o;

        int u,y;

        long x,w,f;

        for(int i=0;i<N;i++) {

            u=0;

            for(int j=0;j<PP;j++) {

                y=(1<<j);

                if((y&i)==y) {

                    u|=(1<<(PP-1-j));

                }

            }

            if(i<u) {

                o=in[i];//swap

                in[i]=in[u];

                in[u]=o;

            }

        }

        for(int k=1;k<N;k<<=1){

            w=fast(G,(long)(P-1)/(k<<1)*(P-1+inv));

            for(int j=0;j<N;j+=k<<1){

                x=1;

                for(int i=j;i<j+k;i++,x=x*w% P){

                    f=x*in[i+k]%P;

                    in[i+k]=(in[i]-f+P)%P;

                    in[i]=(in[i]+f)%P;

                }

            }

        }

    }



    

    public static long fast(long x,long pw) {

        if(pw==0)return 1;

        if(pw==1) {

            return x;

        }

        else {

            long h=fast(x,pw>>1);

            if((pw&1)==0) {

                return h*h%P;

            }

            else {

                return h*h%P*x%P;

            }

        }

    }

}

 

 

 

 

 

 

文章標籤
全站熱搜
創作者介紹
創作者 En Chi Tsung 的頭像
En Chi Tsung

阿祁的部落格

En Chi Tsung 發表在 痞客邦 留言(0) 人氣(5)