re求助
查看原帖
re求助
360025
zzyaba楼主2024/7/23 21:42
#include<bits/stdc++.h>
#define MAXN 16
#define sz (1<<MAXN)
using namespace std;
struct z{
	double a,b;
	z(double _a=0,double _b=0):a(_a),b(_b){
	}
	z operator=(double _a){
		a=_a;
		b=0;
	}
	z operator+(z o){
		return z(a+o.a,b+o.b);
	}
	z operator-(z o){
		return z(a-o.a,b-o.b);
	}
	z operator*(z o){
		return z(a*o.a-b*o.b,a*o.b+b*o.a);
	}
	z operator~(){
		return z(a/2,b/2);
	}
	z operator-(){
		return z(-a,-b);
	}
	z operator!(){
		return z(a,-b);
	}
}o,qpow[sz],t[4];
istream&operator>>(istream&x,z&b){
	b.b=0;
	return x>>b.a;
}
ostream&operator<<(ostream&x,z b){
	if(abs(b.a)>=1e-6){
		if(abs(b.b)>=1e-6){
			if(b.b>0){
				x<<b.a<<"+"<<b.b<<"i";
			}else{
				x<<b.a<<"-"<<-b.b<<"i";
			}
		}else{
			x<<b.a;
		}
	}else{
		if(abs(b.b)>=1e-6){
			x<<b.b<<"i";
		}else{
			x<<0;
		}
	}
	return x;
}
int n,m,l;
z a[sz],b[sz],pre[sz],l1,l2;
void fft(z*a,int len){
	for(int i=0;i<len;i++){
		l=0;
		for(int j=0;j<MAXN;j++){
			if(i&(1<<j)){
				l+=(1<<MAXN-j-1);
			}
		}
		pre[l]=a[i];
	}
	for(int len=2;len<=sz;len<<=1){
		for(z*s=pre;s<pre+sz;s+=len){
			for(int i=0;i<len/2;i++){
				l1=s[i];
				l2=s[len/2+i];
				s[i]=l1+l2*qpow[i*sz/len%sz];
				s[len/2+i]=l1-l2*qpow[i*sz/len%sz];
			}
		}
	}
	memcpy(a,pre,sizeof(pre));
}
void dfft(z*a,int len){
	for(int len=sz;len>=2;len>>=1){
		for(z*s=a;s<a+sz;s+=len){
			for(int i=0;i<len/2;i++){
				l1=s[i];
				l2=s[len/2+i];
				s[i]=(~(l1+l2));
				s[len/2+i]=(~(l1-l2))*qpow[(sz-i*sz/len)%sz];
			}
		}
	}
	for(int i=0;i<len;i++){
		l=0;
		for(int j=0;j<MAXN;j++){
			if(i&(1<<j)){
				l+=(1<<MAXN-j-1);
			}
		}
		pre[i]=a[l]*t[MAXN%4];
	}
	memcpy(a,pre,sizeof(pre));
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	o=z(cos(acos(-1.)*2/sz),sin(acos(-1.)*2/sz));
	qpow[0]=1;
	for(int i=1;i<sz;i++){
		qpow[i]=qpow[i-1]*o;
	}
	t[0]=1;
	for(int i=1;i<4;i++){
		t[i]=t[i-1]*z(0,-1);
	}
	cin>>n>>m;
	for(int i=0;i<=n;i++){
		cin>>a[i];
	}
	for(int i=0;i<=m;i++){
		cin>>b[i];
	}
	fft(a,sz);
	fft(b,sz);
	for(int i=0;i<sz;i++){
		a[i]=a[i]*b[i];
	}
	dfft(a,sz);
	for(int i=0;i<=n+m;i++){
		cout<<a[i]<<" ";
	}
}

如果把MAXN调整到17及以上会在dfft()的第一个大循环的第三层中在i=1100000,len=1048576时将i<len/2判断为1

2024/7/23 21:42
加载中...