HDU-1402 A * B Problem Plus FFT模板题
Description
Calculate A * B.
Input
Each line will contain two integers A and B. Process to end of file.
Note: the length of each integer will not exceed 50000.
Output
For each case, output A * B in one line.
Sample Input
1
2
1000
2
Sample Output
2
2000
题解
fft入门题,这里取\(x=10\),那么个位数就对应\(x^0\),十位数对应\(x^1\)....将对应的系数用每位上的数字代替,fft即可,点值相乘后再求逆得到系数,系数也就是结果,最后进位化简一下即可。
代码
#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 2e5 + 50;
typedef long long ll;
struct cp {
double r, i;
cp(double r = 0, double i = 0): r(r), i(i) {}
cp operator + (const cp &b) {
return cp(r + b.r, i + b.i);
}
cp operator - (const cp &b) {
return cp(r - b.r, i - b.i);
}
cp operator * (const cp &b) {
return cp(r * b.r - i * b.i, r * b.i + i * b.r);
}
};
void change(cp a[], int len) {
for (int i = 1, j = len / 2; i < len - 1; i++) {
if (i < j) swap(a[i], a[j]);
int k = len / 2;
while (j >= k) {
j -= k;
k /= 2;
}
if (j < k) j += k;
}
}
void fft(cp a[], int len, int op) {
change(a, len);
for (int h = 2; h <= len; h <<= 1) {
cp wn(cos(-op * 2 * pi / h), sin(-op * 2 * pi / h));
for (int j = 0; j < len; j += h) {
cp w(1, 0);
for (int k = j; k < j + h / 2; k++) {
cp u = a[k];
cp t = w * a[k + h / 2];
a[k] = u + t;
a[k + h / 2] = u - t;
w = w * wn;
}
}
}
if (op == -1) {
for (int i = 0; i < len; i++) {
a[i].r /= len;
}
}
}
cp a[N]; cp b[N];
char sa[N], sb[N];
int ans[N];
int main() {
while (~scanf("%s%s", sa, sb)) {
int la = strlen(sa), lb = strlen(sb);
for (int i = 0; i < la; i++) {
a[i] = cp(sa[la - i - 1] - '0', 0);
}
for (int i = 0; i < lb; i++) {
b[i] = cp(sb[lb - i - 1] - '0', 0);
}
int len1 = max(la, lb);
int len = 1;
while (len < len1 * 2) len <<= 1;
for (int i = la; i < len; i++) {
a[i] = cp(0, 0);
}
for (int i = lb; i < len; i++) {
b[i] = cp(0, 0);
}
fft(a, len, 1);
fft(b, len, 1);
for (int i = 0; i < len; i++) {
a[i] = a[i] * b[i];
}
fft(a, len, -1);
for (int i = 0; i < len; i++) {
ans[i] = (int)(a[i].r + 0.5);
}
for (int i = 0; i < len; i++) {
ans[i + 1] += ans[i] / 10;
ans[i] %= 10;
}
len = la + lb - 1;
while (ans[len] <= 0 && len > 0) len--;
for (int i = len; i >= 0; i--) {
putchar(ans[i] + '0');
}
puts("");
}
}