HDU 1402及51 nod1028 大数乘法 V2(FFT 快速傅里叶变换)
发布时间:2020-12-14 01:37:55 所属栏目:大数据 来源:网络整理
导读:1028?大数乘法?V2 基准时间限制:2?秒 空间限制:131072?KB 分值:?80? 难度:5级算法题 ?收藏 ?关注 给出2个大整数A,B,计算A*B的结果。 Input 第1行:大数A第2行:大数B(A,B的长度?=?100000,A,B?=?0) Output 输出A?*?B Input示例 123456234567 Output示例
1028?大数乘法?V2
基准时间限制:2?秒 空间限制:131072?KB 分值:?80?
难度:5级算法题
给出2个大整数A,B,计算A*B的结果。
Input
第1行:大数A 第2行:大数B (A,B的长度?<=?100000,A,B?>=?0)
Output
输出A?*?B
Input示例
123456 234567
Output示例
28958703552 我只是过来存个模板的…… 对于这题来说kuangbin巨巨的不如下面这个速度快会超时, http://blog.csdn.net/caoguo_app_android/article/details/44067483 但是对于HDU1402来说,就已经够用了~
#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h> #include <math.h> using namespace std; const int N = 400005; const double pi = acos(-1.0); const int g=3; //const int len=1<<18; const long long MOD=(479<<21)+1; int len; char A[N],B[N]; long long a[N],b[N],qp[30]; void p(long long a[]) { for(int i=0;i<len;i++)printf("%lld ",a[i]);puts(""); } long long q_pow(long long x,long long y,long long P) { long long ans=1; while(y>0) { if(y&1)ans=ans*x%P; x=x*x%P; y>>=1; } return ans; } void init() { len=1; for(int i=0;i<21;i++) { int t=1<<i; qp[i]=q_pow(g,(MOD-1)/t,MOD); } int len1=strlen(A); int len2=strlen(B); while(len<2*len1||len<2*len2)len<<=1; for(int i=0;i<len1;i++)a[len1-i-1]=A[i]-'0'; for(int i=len1;i<len;i++)a[i]=0; for(int i=0;i<len2;i++)b[len2-i-1]=B[i]-'0'; for(int i=len2;i<len;i++)b[i]=0; } void rader(long long F[],int len) { int j=len/2; for(int i=1;i<len-1;i++) { if(i<j)swap(F[i],F[j]); int k=len/2; while(j>=k) { j-=k; k>>=1; } if(j<k)j+=k; } } void NTT(long long F[],int len,int t) { int id=0; rader(F,len); for(int h=2;h<=len;h<<=1) { id++; for(int j=0;j<len;j+=h) { long long E=1; for(int k=j;k<j+h/2;k++) { long long u=F[k]; long long v=(E*F[k+h/2])%MOD; F[k]=(u+v)%MOD; F[k+h/2]=((u-v)%MOD+MOD)%MOD; E=(E*qp[id])%MOD; } } } //p(F); if(t==-1) { for(int i=1;i<len/2;i++)swap(F[i],F[len-i]); long long inv=q_pow(len,MOD-2,MOD); for(int i=0;i<len;i++)F[i]=(F[i]%MOD*inv)%MOD; } //p(F); } void work() { NTT(a,len,1); NTT(b,1); for(int i=0;i<len;i++) a[i]=(a[i]*b[i])%MOD; NTT(a,-1); } void pushup() { for(int i=0;i<len;i++) { if(a[i]>=10) { a[i+1]+=a[i]/10; a[i]=a[i]%10; } } } void print() { int high=0; for(int i=len-1;i>=0;i--) { if(a[i]) { high=i; break; } } for(int i=high;i>=0;i--)printf("%lld",a[i]); puts(""); } int main() { while(~scanf("%s%s",A,B)) { init(); work(); pushup(); print(); } return 0; }
#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <math.h> using namespace std; const double PI = acos(-1.0); //复数结构体 struct Complex { double x,y;//实部和虚部 x+yi Complex(double _x = 0.0,double _y = 0.0) { x = _x; y = _y; } Complex operator -(const Complex &b)const { return Complex(x-b.x,y-b.y); } Complex operator +(const Complex &b)const { return Complex(x+b.x,y+b.y); } Complex operator *(const Complex &b)const { return Complex(x*b.x-y*b.y,x*b.y+y*b.x); } }; /* * 进行FFT和IFFT前的反转变换。 * 位置i和 (i二进制反转后位置)互换 * len必须去2的幂 */ void change(Complex y[],int len) { int i,j,k; for(i = 1,j = len/2; i <len-1; i++) { if(i < j)swap(y[i],y[j]); //交换互为小标反转的元素,i<j保证交换一次 //i做正常的+1,j左反转类型的+1,始终保持i和j是反转的 k = len/2; while(j >= k) { j -= k; k /= 2; } if(j < k)j += k; } } /* * 做FFT * len必须为2^k形式, * on==1时是DFT,on==-1时是IDFT */ void fft(Complex y[],int on) { change(y,len); for(int h = 2; h <= len; h <<= 1) { Complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h)); for(int j = 0; j < len; j+=h) { Complex w(1,0); for(int k = j; k < j+h/2; k++) { Complex u = y[k]; Complex t = w*y[k+h/2]; y[k] = u+t; y[k+h/2] = u-t; w = w*wn; } } } if(on == -1) for(int i = 0; i < len; i++) y[i].x /= len; } const int MAXN = 200010; Complex x1[MAXN],x2[MAXN]; char str1[MAXN/2],str2[MAXN/2]; int sum[MAXN]; int main() { while(scanf("%s%s",str1,str2)==2) { int len1 = strlen(str1); int len2 = strlen(str2); int len = 1; while(len < len1*2 || len < len2*2)len<<=1; for(int i = 0; i < len1; i++) x1[i] = Complex(str1[len1-1-i]-'0',0); for(int i = len1; i < len; i++) x1[i] = Complex(0,0); for(int i = 0; i < len2; i++) x2[i] = Complex(str2[len2-1-i]-'0',0); for(int i = len2; i < len; i++) x2[i] = Complex(0,0); //求DFT fft(x1,1); fft(x2,1); for(int i = 0; i < len; i++) x1[i] = x1[i]*x2[i]; fft(x1,-1); for(int i = 0; i < len; i++) sum[i] = (int)(x1[i].x+0.5); for(int i = 0; i < len; i++) { sum[i+1]+=sum[i]/10; sum[i]%=10; } len = len1+len2-1; while(sum[len] <= 0 && len > 0)len--; for(int i = len; i >= 0; i--) printf("%c",sum[i]+'0'); printf("n"); } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |