The principle of rapid number theory change (NTT) is actually the same principle as the fast Fourier transform. For the Fermat prime of a shape such as m= c*2^n+1, it is assumed that its original root is G. So deceive g^ (m-1) ==1 and just (m-1) can divide 2^n. So the NTT transform can be performed in the modulo p field. The rotation factor is g^ ((m-1)/n). The other principles are the same as the FFT principle. This solves the floating-point error of the FFT in special cases.
/* * Author:islands * Created time:2015/7/30 9:25:47 * File Name:test.cpp */#include <iostream> #include <cst dio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> #include <set> #include < time.h>using namespace std; #define MP (x, y) make_pair (x, y) const int inf = 0x3fffffff;typedef long long ll;const int Mmax = 1<<18;const int mod = (479<<21) +1;const int g = 3; Original Root ll quick_mod (ll A,ll b) {ll ans=1; for (; b;b/=2) {if (b&1) Ans=ans*a%mod; A=a*a%mod; } return ans; int rev (int x,int R)//butterfly operation {int ans=0; for (int i=0; i<r; i++) {if (x& (1<<i)) {ans+=1<< (r-i-1); }} return ans; void NTT (int n,ll a[],int on)//length n (2 times) {int r=0; for (;; r++) {if ((1<<r) ==n) break; } for (int i=0; i<n; i++) {int Tmp=rev (I,R); if (i<tmp) swap (a[i],a[tmp]); } for (int s=1; s<=r; s++) {int m=1<<s; LL Wn=quick_mod (g, (mod-1)/m); for (int k=0; k<n; k+=m) {LL w=1; for (int j=0; j<m/2; J + +) {LL t,u; t=w* (a[k+j+m/2]%mod)%mod; U=a[k+j]%mod; a[k+j]= (u+t)%mod; A[k+j+m/2]= ((u-t)%mod+mod)%mod; W=w*wn%mod; }}} if (On==-1) {for (int i=1;i<n/2;i++) swap (a[i],a[n-i]); LL Inv=quick_mod (n,mod-2); for (int i=0;i<n;i++) A[i]=a[i]%mod*inv%mod; }}ll a[mmax+10],b[mmax+10]; LL Ans[mmax+10];int Main () {//freopen ("In.txt", "R", stdin); int n,m; string S1; String S2; while (CIN>>S1>>S2) {n=s1.size (); M=s2.size (); memset (a,0,sizeof A); memset (b,0,sizeof B); for (int i=n-1; i>=0; i--) a[i]=s1[n-i-1]-' 0 '; for (int i=m-1; i>=0; i--) b[i]=s2[m-i-1]-' 0 '; int tmp=1; while (Tmp<max (n,m)) tmp*=2; n=tmp; NTT (2*n,a,1); NTT (2*n,b,1); for (int i=0; i<2*n; i++) A[i]=a[i]*b[i]%mod; NTT (2*n,a,-1); Memset (ans,0,sizeof ans); for (int i=0;i<2*n;i++) {ans[i]+=a[i]; if (ans[i]>=10) {ANS[I+1]+=ANS[I]/10; ans[i]%=10; }} int e=0; for (int i=2*n-1;i>=0;i--) {if (Ans[i]) {e=i; Break }} for (int i=e;i>=0;i--) {printf ("%lld", Ans[i]); } printf ("\ n"); }}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Fast number theory Transformation Template (NTT)