Title Description
Given two $ $ n-digit decimal numbers x and y, find x * y (see Luo Valley P1919 )
analysis
Assumptions have learned FFT / NTT.
Polynomial multiplication except special cases precision multiplication, when corresponding to $ x = 10 $.
For example n = 3, * 111 123 seek
$$ 123 = x ^ 2 + 2x + 3 $$
$$111 = x^2 + x +1$$
$$\begin{aligned}123 * 111 &= (x^2 + 2x + 3)(x^2 + x +1)\\ &= x^4 + 3x^3 + 6x^2 + 5x + 3\\ &= 13653\end{aligned}$$
Code:
#include<bits/stdc++.h> #define rg register using namespace std; typedef long long ll; const int mod=998244353,g=3; const int maxn = 6e4 + 10; inline int qpow(int x,int k) { int ans=1; while(k) { if(k&1) ans=(ll)ans*x%mod; x=(ll)x*x%mod,k>>=1; } return ans; } inline int module(int x,int y) { x+=y; if(x>=mod) x-=mod; return x; } int rev[4*maxn]; inline void NTT(int*t,int lim,int type) { for(rg int i=0;i<lim;++i) if(i<rev[i]) swap(t[i],t[rev[i]]); for(rg int i=1;i<lim;i<<=1) { int gn=qpow(g,(mod-1)/(i<<1)); if(type==-1) gn=qpow(gn,mod-2); for(rg int j=0;j<lim;j+=(i<<1)) { int gi=1; for(rg int k=0;k<i;++k,gi=(ll)gi*gn%mod) { int x=t[j+k],y=(ll)gi*t[j+i+k]%mod; t[j+k]=module(x,y); t[j+i+k]=module(x,mod-y); } } } if(type==-1) { int inv=qpow(lim,mod-2); for(rg int i=0;i<lim;++i) t[i]=(ll)t[i]*inv%mod; } } int X[4*maxn],Y[4* MAXN]; inline void MUL ( int * X, int * Y, int n-, int m) { Memset (X-, 0 , the sizeof (X-)); Memset (the Y, 0 , the sizeof (the Y)); int Lim = . 1 , L = 0 ; // L = 0 must be written, the default value is a local variable may not 0 the while (Lim <= n-m +) = Lim << . 1 , L ++; // Lim greater than (n + m) of power of 2, it is up to 4 times the space for ( int I = 0 ; I <Lim; I ++) Rev [I] = (Rev [I >> . 1] >> 1) | ((i & 1) << (L - 1)); for(rg int i=0;i<lim;++i) X[i]=x[i],Y[i]=y[i]; NTT(X,lim,1); NTT(Y,lim,1); for(rg int i=0;i<lim;++i) X[i]=(ll)X[i]*Y[i]%mod; NTT(X,lim,-1); for(rg int i=0;i<lim;++i) x[i]=X[i]; } int n; int a[4*maxn], b[4*maxn]; char s[maxn]; int main() { scanf("%d", &n); scanf("%s", s); for(int i = 0;i < n;i++) a[i] = s[n-1-i] - '0'; scanf("%s", s); for(int i = 0;i < n;i++) b[i] = s[n-1-i] - '0'; mul(a, b, n, n); // for(int i = 0;i < 2*n;i++) printf("%d ", a[i]); // printf("\n"); int tmp = 0; //进位 for(int i = 0;i < 2*n;i++) // { a[i] = a[i] + tmp; tmp = a[i] / 10; a[i] = a[i] % 10; } // for(int i = 0;i < 2*n;i++) printf("%d ", a[i]); // printf("\n"); bool flag = true; for(int I = 2 * n-; I> = 0 ; i--) // reverse order output, removing the leading zeros { IF (In Flag && A [I] == 0 ) Continue ; the printf ( " % D " , A [I] ); In Flag = to false ; } return 0 ; }