又是我来debug了不好意思(
参考了b站董晓算法的代码,只用函数FFT做正逆变换就全AC过了。 但是如果改成FFT2做正变换会WA一个点;改成FFT2做逆变换更是只AC了两个点 /(ㄒoㄒ)/~~ 欢迎大佬指正
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <complex.h>
#include <math.h>
#define M_PI 3.14159265358979323846
void FFT2(complex a[],int n,int b)
{
int i,j,k; //1.蝴蝶变换更快(不用递归
int *r=(int*)calloc(n,sizeof(int));
r[0]=0;
for (i=0;i<n;i++) {
r[i]=r[i/2]/2+(i&1)*n/2;
// printf("%d %d\n",i,r[i]);
}
for (i=0;i<n>>1;i++) {
if (i<r[i]){
int t=a[i];
a[i]=a[r[i]];
a[r[i]]=t;
}
}
// for (i=0;i<n;i++) printf("%d %d\n",i,r[i]); //测试
for (k=2;k<=n;k<<=1){
complex w1=cos(2*M_PI/k)+I*sin(2*M_PI/k)*b;
for (i=0;i<n;i+=k){
complex wk=1;
for (j=0;j<k/2;j++){
complex x=a[i+j],y=a[i+j+k/2]*wk;
a[i+j]=x+y;
a[i+j+k/2]=x-y;
wk*=w1;
}
}
}
free(r);
}
void FFT(complex a[],int n,int b)
{
if (n==1) return;
int i;
complex a1[n/2],a2[n/2]; //2.递归变换
for (i=0;i<n/2;i++){
a1[i]=a[2*i];
a2[i]=a[2*i+1];
}
FFT(a1,n/2,b); FFT(a2,n/2,b);
complex w1=cos(2*M_PI/n)+I*sin(2*M_PI/n)*b;
complex wk=1;
for (i=0;i<n/2;i++){
a[i]=a1[i]+a2[i]*wk;
a[i+n/2]=a1[i]-a2[i]*wk;
wk*=w1;
}
}
int main()
{
complex a[5000000],b[5000000];
int m,n,i;
scanf("%d%d",&n,&m); //最高项次数
for (i=0;i<=n;i++) scanf("%lf",&a[i]); //项数 = max次数 + 1
for (i=0;i<=m;i++) scanf("%lf",&b[i]);
for (m=m+n,n=1;n<=m;n<<=1);
// printf("%d\n",n); //测试
FFT2(a,n,1); FFT2(b,n,1);
for (i=0;i<n;i++) a[i]*=b[i];
FFT(a,n,-1); //这里用2会出错
for (i=0;i<=m;i++) printf("%d ",(int)(creal(a[i])/n+0.5));
return 0;
}