1. 程式人生 > >洛谷P1919 【模板】A*B Problem升級版(FFT快速傅裏葉)

洛谷P1919 【模板】A*B Problem升級版(FFT快速傅裏葉)

題目 計算 printf n) freopen sam 升級 double 輸入輸出格式

題目描述

給出兩個n位10進制整數x和y,你需要計算x*y。

輸入輸出格式

輸入格式:

第一行一個正整數n。 第二行描述一個位數為n的正整數x。 第三行描述一個位數為n的正整數y。

輸出格式:

輸出一行,即x*y的結果。(註意判斷前導0)

輸入輸出樣例

輸入樣例#1: 復制
1
3
4
輸出樣例#1: 復制
12

說明

數據範圍:

n<=60000

來源:bzoj2179

本題數據為洛谷自造數據,使用CYaRon耗時5分鐘完成數據制作。

emmmm感覺學了FFT沒什麽亂用啊,,

也就來水一水這種板子吧。

思路很簡單,將每一位看成多項式的系數。

來一遍FFT

最後去掉前導0

輸出

不過話說我的FFT怎麽這麽慢

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
const int MAXN=1e5+10;
const double Pi=acos(-1.0);
int r[MAXN],l=0,limit=1,c[MAXN];
char sa[MAXN],sb[MAXN];
struct complex
{
    double x,y;
    complex(double
xx=0,double yy=0){x=xx,y=yy;} }a[MAXN],b[MAXN]; complex operator + (complex a,complex b){return complex(a.x+b.x,a.y+b.y);} complex operator - (complex a,complex b){return complex(a.x-b.x,a.y-b.y);} complex operator * (complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);} void FFT(complex *a,int
type) { for(int i=0;i<limit;i++) if(i<r[i]) swap(a[i],a[r[i]]); for(int mid=1;mid<limit;mid<<=1) { complex Wn(cos(Pi/mid),type*sin(Pi/mid) ); for(int R=mid<<1,j=0;j<limit;j+=R) { complex w(1,0); for(int k=0;k<mid;k++,w=w*Wn) { complex x=a[j+k],y=w*a[j+k+mid]; a[j+k]=x+y; a[j+k+mid]=x-y; } } } } int main() { #ifdef WIN32 freopen("a.in","r",stdin); #else #endif int N; scanf("%d",&N);N--; scanf("%s%s",sa,sb); for(int i=0;i<=N;i++) a[i].x=sa[N-i]-0,b[i].x=sb[N-i]-0; while(limit<=N*2) limit<<=1,l++; for(int i=0;i<=limit;i++) r[i]=(r[i>>1]>>1) | ((i&1)<<(l-1) ); FFT(a,1); FFT(b,1); for(int i=0;i<=limit;i++) a[i]=a[i]*b[i]; FFT(a,-1); for(int i=0;i<=limit;i++) c[i]=(int)(a[i].x/limit+0.5); //for(int i=1;i<=limit;i++) printf("%d ",c[i]);printf("\n"); for(int i=0;i<=limit;i++) { if(c[i]>10) { c[i+1]+=c[i]/10,c[i]%=10; if(i+1>limit) limit++; } } for(int i=limit;i>=0;i--) if(c[i]==0) limit--; else break; for(int i=limit;i>=0;i--) printf("%d",c[i]); return 0; }

洛谷P1919 【模板】A*B Problem升級版(FFT快速傅裏葉)