模板 NTT 快速数论变换
Posted guapisolo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板 NTT 快速数论变换相关的知识,希望对你有一定的参考价值。
NTT裸模板,没什么好解释的
这种高深算法其实也没那么必要知道原理
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N (1<<17)+10 5 #define ll long long 6 using namespace std; 7 8 ll inv3,invl; 9 int r[N]; 10 ll A[N],B[N],C[N],mulwn[N],invwn[N]; 11 char s1[N],s2[N]; 12 const ll p=998244353; 13 ll qpow(ll x,ll y,ll mo){ 14 ll ans=1; 15 while(y){ 16 if(y&1) ans=(ans*x)%mo; 17 x=(x*x)%mo,y>>=1; 18 }return ans; 19 } 20 void pre(int len,int l) 21 { 22 inv3=qpow(3,p-2,p),invl=qpow(len,p-2,p); 23 for(int i=0;i<len;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1)); 24 for(ll i=1;i<=len;i<<=1) mulwn[i]=qpow(3,(p-1)/i,p); 25 for(ll i=1;i<=len;i<<=1) invwn[i]=qpow(mulwn[i],p-2,p); 26 } 27 void NTT(ll *a,int len,int type) 28 { 29 for(int i=0;i<len;i++) 30 if(i<r[i]) swap(a[i],a[r[i]]); 31 for(int k=2;k<=len;k<<=1) 32 { 33 ll wn=(type>0)?mulwn[k]:invwn[k]; 34 int mid=k>>1; 35 for(int i=0;i<len;i+=k) 36 { 37 ll w=1; 38 for(int j=0;j<mid;j++,w=(w*wn)%p) 39 { 40 ll t=(w*a[i+j+mid])%p; 41 a[i+j+mid]=(a[i+j]-t+p)%p; 42 a[i+j]=(a[i+j]+t)%p; 43 } 44 } 45 } 46 if(type==-1) 47 for(int i=0;i<len;i++) 48 a[i]=(a[i]*invl)%p; 49 } 50 void NTT_main(ll *a,ll *b,ll *c,int len,int l) 51 { 52 NTT(a,len,1);NTT(b,len,1); 53 for(int i=0;i<len;i++) c[i]=(a[i]*b[i])%p; 54 NTT(c,len,-1); 55 } 56 57 int main() 58 { 59 int n,len=1,l=0;scanf("%d",&n); 60 scanf("%s",s1),scanf("%s",s2); 61 for(int i=0;i<n;i++) A[n-i-1]=s1[i]-‘0‘; 62 for(int i=0;i<n;i++) B[n-i-1]=s2[i]-‘0‘; 63 while(len<n+n) len<<=1,l++; 64 pre(len,l); 65 NTT_main(A,B,C,len,l); 66 for(int i=0;i<len;i++) 67 if(C[i]>9) C[i+1]+=C[i]/10,C[i]%=10; 68 int j=len; 69 while(C[j]==0) j--; 70 while(j>-1) printf("%lld",C[j]),j--; 71 puts(""); 72 return 0; 73 } 74 75 76
以上是关于模板 NTT 快速数论变换的主要内容,如果未能解决你的问题,请参考以下文章