Number theory transformation NTT
Pre-knowledge
FFT: NTT thought and as FFT ( FFT presentation )
Outline
Number theory transformation, namely NTT (Number Theory Transformation?), Is based on the FFT domain of number theory, we generally default to FFT fast Fourier transform on the negative domain, and NTT distinction.
We know, using an FFT unit complex roots periodically to \ (\ Theta (N \ log N) \) computational complexity \ (N \) polynomial set value. NTT is actually FFT on the field of number theory, which uses periodic modulo prime number, and FFT reach the same effect.
Primitive root
If \ (A \) mode \ (P \) is equal to the order of \ ([Phi] (P) \) , called \ (A \) modulo \ (P \) is a primitive root (this definition is not important).
For prime \ (P \) , if the \ (G \) is \ (P \) primitive root, then \ (g ^ i \ mod P \) results of pairwise disjoint; or \ (g ^ t = 1 (\ mod P) \) if and only if the index \ (t = P-1 \ ) when established.
We have found that the nature and the original unit of negative root root properties correspond, reciprocity is satisfied and the periodic cycle, and it may be used substituting the interpolation.
NTT
We have a discrete Fourier transform formula
\ [X_k = \ sum ^ {N-1} _ {n = 0} {x_ne ^ {- \ frac {2 \ pi i} {N} nk}} \ \ \ \ \ \ \ \ \ \ \ \ ( k = 0,1, ..., N-1) \]
And inverse transformation formula
\ [X_k = \ frac {1} {N} \ sum ^ {N-1} _ {n = 0} {x_ne '{\ frac {2 \ pi i} {N} nk}} \ \ \ \ \ \ \ \ \ \ \ \ (k = 0,1, ..., N-1) \]
We only need the original root \ (g ^ {\ frac { P-1} {N}} (\ mod P) \) Alternatively Unit complex roots \ (e ^ {- \ frac {-2 \ pi i} {N }} \) , you can get
\ [X_k = \ sum ^ {N-1} _ {n = 0} ^ {nk x_ng {}} (\ mod P) \ \ \ \ \ \ \ \ \ \ \ \ (k = 0,1 ,. .., n-1) \]
with
\ [X_k = \ frac {1} {N} \ sum ^ {N-1} _ {n = 0} {x_ng ^ {- nk}} (\ mod P) \ \ \ \ \ \ \ \ \ \ \ \ (k = 0,1, ..., N-1) \]
achieve
And almost the same FFT template, using the original root \ (g ^ {\ frac { P-1} {N}} (\ mod P) \) Alternatively Unit complex roots \ (e ^ {- \ frac {-2 \ pi i} {N}} \) to
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF=1e9+7,MAXN=3e6+10/*Min:2^20+10*/;
const LL BASE=3,MOD=998244353,INV=332748118;
inline LL fpm(LL base,LL p){
LL ret=1;
while(p){
if(p&1)
ret=ret*base%MOD;
base=base*base%MOD;
p>>=1;
}
return ret%MOD;
}
int N,M,limit=1,lg,rev[MAXN];
inline void NTT(LL *a,int type){
for(int i=0;i<limit;i++)
if(i<rev[i])
swap(a[i],a[rev[i]]);
for(int mid=1;mid<limit;mid<<=1){
int len=mid<<1/*n*/;
LL Wn=fpm(type==1?BASE:INV/*BASE^type*/,(MOD-1)/len);
for(int j=0;j<limit;j+=len){
LL w=1;
for(int k=0;k<mid;k++){
int x=a[j+k],y=w*a[j+k+mid]%MOD;
a[j+k]=(x+y)%MOD;
a[j+k+mid]=(x-y+MOD)%MOD;
w=w*Wn%MOD;
}
}
}
}
LL a[MAXN],b[MAXN];
int main(){
scanf("%d%d",&N,&M);
for(int i=0;i<=N;i++){
scanf("%lld",a+i);
a[i]=(a[i]+MOD)%MOD;
}
for(int i=0;i<=M;i++){
scanf("%lld",b+i);
b[i]=(b[i]+MOD)%MOD;
}
while(limit<=N+M){
limit<<=1;
lg++;
}
for(int i=0;i<limit;i++)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
NTT(a,1);
NTT(b,1);
for(int i=0;i<limit;i++)
a[i]=a[i]*b[i]%MOD;
NTT(a,-1);
LL limit_inv=fpm(limit,MOD-2);
for(int i=0;i<=N+M;i++)
printf("%lld ",a[i]*limit_inv%MOD);
return 0;
}
the complexity
time
And FFT, is \ (\ Theta (N \ log N) \) , fast in the case of smaller data than the FFT, but because there is rapid exponential operation, if the number is too large will result in TLE
space
And FFT, is \ (\ Theta (N) \) , but note that the array size is not \ (N + M \) , but not smaller than \ (N + M \) minimum \ (2 \) of the power
Range (select prime)
We need a large prime number to the modulo this prime number greater than the answer to the final output (but if too large, you need to use rapid multiplication)
Here are a few common prime number, inverse primitive roots and primitive roots
Prime numbers | Primitive root | Inverse |
---|---|---|
65537 | 3 | 21846 |
786433 | 10 | 235930 |
5767169 | 3 | 1922390 |
7340033 | 3 | 2446678 |
23068673 | 3 | 7689558 |
104857601 | 3 | 34952534 |
167772161 | 3 | 55924054 |
469762049 | 3 | 156587350 |
998244353 | 3 | 332748118 |
1004535809 | 3 | 334845270 |
2013265921 | 31 | 64944062 |
2281701377 | 3 | 760567126 |
3221225473 | 5 | 1932735284 |
75161927681 | 3 | 25053975894 |
77309411329 | 7 | 22088403237 |
206158430209 | 22 | 84337539631 |
2061584302081 | 7 | 589024086309 |
2748779069441 | 3 | 916259689814 |
6597069766657 | 5 | 2638827906663 |
39582418599937 | 5 | 15832967439975 |
79164837199873 | 5 | 47498902319924 |
263882790666241 | 7 | 150790166094995 |
1231453023109120 | 3 | 410484341036374 |
1337006139375610 | 3 | 445668713125206 |
3799912185593850 | 5 | 1519964874237540 |
4222124650659840 | 19 | 888868347507335 |
7881299347898360 | 6 | 1313549891316390 |
31525197391593400 | 3 | 10508399130531100 |
180143985094819000 | 6 | 30023997515803300 |
1945555039024050000 | 5 | 1167333023414430000 |
4179340454199820000 | 3 | 1393113484733270000 |