BZOJ 2179FFT快速傅立叶

时间:2024-06-20 17:34:02

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2179

题目大意:给出两个n位10进制整数x和y,你需要计算x*y。

题解:FFT,不会的可以膜拜陈老师(非clj)QQ:297086016

代码:

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define inf 1<<30
#define maxm 270005
#define pi acos(-1)
using namespace std;
struct F{
double rea,ima;
F operator +(const F &x){return (F){rea+x.rea,ima+x.ima};}
F operator -(const F &x){return (F){rea-x.rea,ima-x.ima};}
F operator *(const F &x){return (F){rea*x.rea-ima*x.ima,rea*x.ima+ima*x.rea};}
}a[maxm],b[maxm],c[maxm],w,wn,t1,t2;
int n,m,l,ans[maxm],rev[maxm];
void read(F *a)
{
char ch;
while (ch=getchar(),ch<''||ch>'');
for (int i=m-; ch>=''&&ch<='';ch=getchar(),i--) a[i].rea=ch-'';
}
int re(int v)
{
int t=;
for (int i=; i<l; i++) t<<=,t|=v&,v>>=;
return t;
}
void fft(F *a,int type)
{
for (int i=; i<n; i++) if (i<rev[i]) swap(a[i],a[rev[i]]);
for (int s=; s<=n; s<<=)
{
wn=(F){cos(type**pi/s),sin(type**pi/s)};
for (int i=; i<n; i+=s)
{
w=(F){,};
for (int j=i; j<(i+(s>>)); j++,w=w*wn)
{
t1=a[j],t2=w*a[j+(s>>)];
a[j]=t1+t2,a[j+(s>>)]=t1-t2;
}
}
}
}
int main()
{
scanf("%d\n",&m);
for (n=; n<(m<<); n<<=) l++;
for (int i=; i<n; i++) rev[i]=re(i);
read(a); read(b);
fft(a,); fft(b,);
for (int i=; i<n; i++) c[i]=a[i]*b[i];
fft(c,-);
for(int i=;i<n;i++) ans[i]=int(c[i].rea/n+0.5);
for(int i=;i<n;i++) ans[i+]+=ans[i]/,ans[i]=ans[i]%;
int pps=n-;while(ans[pps]==&&pps)pps--;
for(;pps>=;pps--)printf("%d",ans[pps]);printf("\n");
return ;
}