题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1402
题意: 求两个大数的乘积。
思路: 利用FFT来O(nlogn)高效的求解
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define rep(i, n) for(int i=0; i<n; i++)
#define Rep(i, n) for(int i=1; i<=n; i++)
typedef long long ll;
const int MAX_N = 4e5+5;
const int MAX_Q = 0;
const double PI = acos(-1.0);
struct W{
double x, y;
W() {x=y = 0;}
W(double x, double y):x(x),y(y){}
W operator + (W b) { return W(x+b.x, y+b.y); }
W operator - (W b) { return W(x-b.x, y-b.y); }
W operator * (W b) { return W(x*b.x-y*b.y, x*b.y+y*b.x); }
};
W w1[MAX_N], w2[MAX_N];
int ans[MAX_N];
string str_a, str_b;
void change(W* q, int len){
for(int i=1, j = len/2; i<len-1; i++){
if(i<j) swap(q[i], q[j]);
int k = len/2;
while(j>=k){
j -= k;
k /= 2;
}
if(j<k) j+=k;
}
}
void FFT(W* q, int len, int mod){
change(q, len);
for(int h=2; h <= len; h<<=1){
W wn(cos(-mod*2*PI/h), sin(-mod*2*PI/h));
for(int j=0; j<len; j+=h){
W w(1,0);
for(int k=j; k<j+h/2; k++){
W u = q[k];
W t = w*q[k+h/2];
q[k] = u+t;
q[k+h/2] = u-t;
w = w*wn;
}
}
}
if(mod==-1)
for(int i=0;i<len;i++)
q[i].x/=len;
}
void solve(){
int sa, sb, lena = str_a.size(), lenb = str_b.size();
int len;
int mx = max(lena*2, lenb*2);
for(len=1; len<m; len<<=1);
for(int i=0; i<len; i++){
if(i<lena) w1[i] = W(str_a[lena - i - 1] - '0', 0);
else w1[i] = W(0, 0);
if(i<lenb) w2[i] = W(str_b[lenb - i - 1] - '0', 0);
else w2[i] = W(0, 0);
}
FFT(w1, len, 1);
FFT(w2, len, 1);
for(int i=0; i<len; i++){
w1[i] = w1[i] * w2[i];
}
FFT(w1, len, -1);
for(int i=0; i<len; i++){
ans[i] = int(w1[i].x+0.5);
}
for(int i=0; i<len; i++){
ans[i+1] += ans[i]/10;
ans[i] %= 10;
}
for(int i=len-1; i>=0; i--){
if(ans[i]){
for(; i>=0; i--)
printf("%d",ans[i]);
printf("\n");
break;
}
if(i==0)
puts("0");
}
}
int main(){
while(cin>>str_a>>str_b){
solve();
}
}