多项式板子

发布时间 2023-12-22 18:12:43作者: 蒻蒟cdx

FFT

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int limit,r[10000010];
double pie=acos(-1.0);
struct complex{
	double x,y;
	complex(double a=0,double b=0){x=a; y=b;}
};
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 k){
	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 dw=complex(cos(pie/mid),k*sin(pie/mid));
		for(int j=0;j<limit;j+=(mid<<1)){
			complex w=complex(1,0);
			for(int k=j;k<j+mid;k++,w=w*dw){
				complex x=a[k],y=w*a[k+mid];
				a[k]=x+y;
				a[k+mid]=x-y;
			}
		} 
	}
}
void polymul(int n,int m,complex *a,complex *b){
	limit=1;
	int l=0;
	while(limit<=n+m) limit<<=1,l++;
	for(int i=0;i<=limit;i++) a[i].y=b[i].x;
	for(int i=0;i<limit;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
	FFT(a,1);
	for(int i=0;i<=limit;i++) a[i]=a[i]*a[i];
	FFT(a,-1);
	for(int i=0;i<=n+m;i++) a[i].y=(int)(a[i].y/limit/2+0.5);
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	int n,m;
	cin>>n>>m;
	complex *a=(complex* )calloc((n+m)*2+10,sizeof(complex));
	complex *b=(complex* )calloc((n+m)*2+10,sizeof(complex));
	for(int i=0;i<=n;i++) cin>>a[i].x;
	for(int i=0;i<=m;i++) cin>>b[i].x;
	polymul(n,m,a,b);
	for(int i=0;i<=n+m;i++) cout<<(int)(a[i].y)<<' ';
	return 0;
}