2179: FFT快速傅立叶
Time Limit: 10 Sec Memory Limit: 259 MB[ Submit][ Status][ Discuss]
Description
给出两个n位10进制整数x和y,你需要计算x*y。
Input
第一行一个正整数n。 第二行描述一个位数为n的正整数x。 第三行描述一个位数为n的正整数y。
Output
输出一行,即x*y的结果。
Sample Input
1
3
4
3
4
Sample Output
12
数据范围:
n<=60000
数据范围:
n<=60000
HINT
fft,裸的
这个板子真的好,相对于丁神的,优化了一些代码长度
抽时间讲一下fft
#include<algorithm>
#include<iostream>
#include<complex>
#include<cstdio>
#include<cmath>
#define pi acos(-1)
using namespace std;
const int N = 200000 + 5;
typedef complex<double> E;
E a[N],b[N]; char ch[N];
int n,m,L,c[N],r[N];
void fft( E *a, int f ){
for( int i = 0; i < n; i++ ) if( i < r[i] ) swap(a[i],a[r[i]]);
for( int i = 1; i < n; i <<= 1 ){
E wn(cos(pi/i),f*sin(pi/i));
for( int j = 0; j < n; j += (i<<1) ){
E w(1,0);
for( int k = 0; k < i; k++, w *= wn ){
E x = a[j+k], y = w*a[j+k+i];
a[j+k] = x+y; a[j+k+i] = x-y;
}
}
}
if( f == -1 ) for( int i = 0; i < n; i++ ) a[i] /= n;
}
int main(){
scanf("%d", &n); n--;
scanf("%s", ch); for( int i = 0; i <= n; i++ ) a[i] = ch[n-i]-'0';
scanf("%s", ch); for( int i = 0; i <= n; i++ ) b[i] = ch[n-i]-'0';
m = 2*n; for( n = 1; n <= m; n <<= 1 ) L++;
for( int i = 0; i < n; i++ ) r[i] = (r[i>>1]>>1) | ((i&1)<<(L-1));
fft( a, 1 ); fft( b, 1 );
for( int i = 0; i <= n; i++ ) a[i] *= b[i];
fft( a, -1 );
for( int i = 0; i <= m; i++ ) c[i] = (int)(a[i].real()+0.1);
for( int i = 0; i <= m; i++ )
if( c[i] >= 10 ){
c[i+1] += c[i]/10, c[i] %= 10;
if( i == m ) m++;
}
for( int i = m; i >= 0; i-- ) printf("%d", c[i]);
return 0;
}