FFT(lzz)

沃日,结构体里开不了1e7的数组,没法封装,不够优雅。

#include<cstdio>
#include<cmath>
const int N=1e7+10;
const double pi=acos(-1.0);
struct complex{
	double x,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};}
complex operator * (complex a,complex b){return (complex){a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x};}
complex a[N],b[N];
int dg_a,dg_b;

void swap(complex &a,complex &b)
{
	complex k=a; a=b; b=k;
	return;
}

int neg[N];
void fft(complex *A,int type,int limit)
{
	int k,i,j;
	complex w,wn;
	complex x,y;
	for(k=0;k<limit;k++)if(k<neg[k])swap(A[k],A[neg[k]]);
	for(k=1;k<limit;k<<=1)
	{
		wn=(complex){cos(pi/k),type*sin(pi/k)};
		for(i=0;i<limit;i+=k<<1)
		{
			w=(complex){1,0};
			for(j=0;j<k;j++,w=w*wn)
			{
				x=A[i+j]; y=A[i+j+k]*w;
				A[i+j]=x+y; A[i+j+k]=x-y;
			}
		}
	}
	return;
}
void convolution(complex *A,int &An,complex *B,int Bn)
{
	int k,i,j;
	int limit=1;
	i=0;
	while(limit<=An+Bn)limit<<=1,i++;
	neg[0]=0;
	for(k=1;k<limit;k++)neg[k]=(neg[k>>1]>>1) | ((k&1)<<(i-1));
	fft(A,1,limit);
	fft(B,1,limit);
	for(k=0;k<limit;k++)A[k]=A[k]*B[k];
	fft(A,-1,limit);
	for(k=0;k<=An+Bn;k++)A[k].x/=limit;
	An+=Bn;
	return;
} 
int main()
{
	int k,i,j;
	scanf("%d%d",&dg_a,&dg_b);
	for(k=0;k<=dg_a;k++)
	{
		scanf("%lf",&a[k].x);
		a[k].y=0;
	}
	for(k=0;k<=dg_b;k++)
	{
		scanf("%lf",&b[k].x);
		b[k].y=0;
	}
	convolution(a,dg_a,b,dg_b); //&a,&dg_a
	for(k=0;k<=dg_a;k++)printf("%d ",int(a[k].x+0.5));
	return 0;
}

posted @ 2022-03-15 22:31  wild_chicken  阅读(41)  评论(0)    收藏  举报