标签:长度 eof -- dft scope data- http efi memset
r·2^k+1 | r | k | g |
---|---|---|---|
3 | 1 | 1 | 2 |
5 | 1 | 2 | 2 |
17 | 1 | 4 | 3 |
97 | 3 | 5 | 5 |
193 | 3 | 6 | 5 |
257 | 1 | 8 | 3 |
7681 | 15 | 9 | 17 |
12289 | 3 | 12 | 11 |
40961 | 5 | 13 | 3 |
65537 | 1 | 16 | 3 |
786433 | 3 | 18 | 10 |
5767169 | 11 | 19 | 3 |
7340033 | 7 | 20 | 3 |
23068673 | 11 | 21 | 3 |
104857601 | 25 | 22 | 3 |
167772161 | 5 | 25 | 3 |
469762049 | 7 | 26 | 3 |
998244353 | 119 | 23 | 3 |
1004535809 | 479 | 21 | 3 |
2013265921 | 15 | 27 | 31 |
2281701377 | 17 | 27 | 3 |
3221225473 | 3 | 30 | 5 |
75161927681 | 35 | 31 | 3 |
77309411329 | 9 | 33 | 7 |
206158430209 | 3 | 36 | 22 |
2061584302081 | 15 | 37 | 7 |
2748779069441 | 5 | 39 | 3 |
6597069766657 | 3 | 41 | 5 |
39582418599937 | 9 | 42 | 5 |
79164837199873 | 9 | 43 | 5 |
263882790666241 | 15 | 44 | 7 |
1231453023109121 | 35 | 45 | 3 |
1337006139375617 | 19 | 46 | 3 |
3799912185593857 | 27 | 47 | 5 |
4222124650659841 | 15 | 48 | 19 |
7881299347898369 | 7 | 50 | 6 |
31525197391593473 | 7 | 52 | 3 |
180143985094819841 | 5 | 55 | 6 |
1945555039024054273 | 27 | 56 | 5 |
4179340454199820289 | 29 | 57 | 3 |
以上是一份NTT专用模数与原根的对照表……
然后从网上爬了一份NTT代码:http://www.cnblogs.com/candy99/p/6641972.html
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; #define N ((1<<18)+5) #define MOD 1004535809ll ll Quick_Pow(ll a,ll p){ if(p==0){ return 1ll; } ll res=Quick_Pow(a,p>>1); res=res*res%MOD; if((p&1ll)==1ll){ res=(a%MOD*res)%MOD; } return res; } struct NTT{ int n,rev[N]; ll g; void ini(int lim) { g=3;//1004535809,998244353的原根都是3 n=1; int k=0; while(n<lim){ n<<=1; ++k; } for(int i=0;i<n;++i){ rev[i]=((rev[i>>1]>>1)|((i&1)<<(k-1))); } } void dft(ll a[],int DFT) { for(int i=0;i<n;++i){ if(i<rev[i]){ swap(a[i],a[rev[i]]); } } for(int l=2;l<=n;l<<=1){ int m=l>>1; ll wn=Quick_Pow(g,DFT==1 ? (MOD-1ll)/(ll)l : MOD-1ll-(MOD-1ll)/(ll)l); for(int i=0;i<n;i+=l){ ll w=1; for(int k=0;k<m;++k){ ll t=w*a[i+k+m]%MOD; a[i+k+m]=(a[i+k]-t+MOD)%MOD; a[i+k]=(a[i+k]+t)%MOD; w=w*wn%MOD; } } } if(DFT==-1){ ll inv=Quick_Pow(n,MOD-2ll); for(int i=0;i<n;++i){ a[i]=a[i]*inv%MOD; } } } void mul(ll a[],ll b[],int len) { ini(len); dft(a,1); dft(b,1); for(int i=0;i<n;++i){ a[i]=a[i]*b[i]; } dft(a,-1); } }ntt; int len1,len2,len,c[N]; ll a[N],b[N]; char s1[N],s2[N]; int main() { // freopen("ntt.in","r",stdin); while(scanf("%s%s",s1,s2)!=EOF){ memset(c,0,sizeof(c)); memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); len1=strlen(s1); len2=strlen(s2); for(int i=0;i<len1;++i){ a[i]=s1[len1-i-1]-‘0‘; } for(int i=0;i<len2;++i){ b[i]=s2[len2-i-1]-‘0‘; } len=len1+len2-1; ntt.mul(a,b,len); for(int i=0;i<len;++i){ c[i]=a[i]; } for(int i=0;i<len;++i){ c[i+1]+=c[i]/10; c[i]%=10; } // if(c[len]){ // ++len; // }//两个数乘积的长度要么是A+B-1,要么是A+B。 // for(int i=len-1;i>=0;--i){ // printf("%d",c[i]); // } // puts(""); for(int i=len;i>=0;--i){ if(c[i]!=0 || i==0){ for(int j=i;j>=0;--j){ printf("%d",c[j]); } puts(""); break; } } } return 0; }
【NTT】hdu1402 A * B Problem Plus
标签:长度 eof -- dft scope data- http efi memset
原文地址:http://www.cnblogs.com/autsky-jadek/p/7545466.html