FFT压位求助
查看原帖
FFT压位求助
514727
bcdmwSjy楼主2022/11/12 21:41

请问一下FFT乘法能不能压位啊?

《理性愉悦——高精度数值计算(2012WC)》里说FFT是可以压位的啊,但是我的代码只压了2位就WA了

求帮助,谢谢dalao

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll DIGIT=1;
const ll BASE=pow(10,DIGIT);
const int maxn=2097153;
const double pi=acos(-1.0);

struct Complex {
	double r,i;
	Complex() {
		r=0,i=0;
	}
	Complex(double _r,double _i) {
		r=_r,i=_i;
	}
	Complex operator + (Complex b) {
		return Complex(r+b.r,i+b.i);
	}
	Complex operator - (Complex b) {
		return Complex(r-b.r,i-b.i);
	}
	Complex operator * (Complex b) {
		return Complex(r*b.r-i*b.i,r*b.i+i*b.r);
	}
};

Complex F[maxn],G[maxn];
ll rev[maxn],len,lim=1;
ll f[maxn];

void FFT(Complex *a,int opt) {
	for (int i=0; i<lim; i++) {
		if (i<rev[i]) {
			swap(a[i],a[rev[i]]);
		}
	}
	double tmp=log2(lim);
	for (int dep=1; dep<=tmp; dep++) {
		ll m=1<<dep;
		Complex wn=Complex(cos(2*pi/m),opt*sin(2*pi/m));
		for (ll i=0; i<lim; i+=m) {
			Complex w=Complex(1.0,0.0);
			for (ll j=0; j<m/2; j++) {
				Complex t=w*a[i+j+m/2];
				Complex u=a[i+j];
				a[i+j]=u+t;
				a[i+j+m/2]=u-t;
				w=w*wn;
			}
		}
	}
	if (opt==-1) {
		for (ll i=0; i<lim; i++) {
			a[i].r/=lim;
		}
	}
}

int main() {
	ios::sync_with_stdio(false);
	string a,b;
	int n,m;
	cin>>a>>b;
	if (a=="0" or b=="0") {
		cout<<"0";
		return 0;
	}
	reverse(a.begin(),a.end());
	reverse(b.begin(),b.end());

	n=ceil(1.0*a.length()/DIGIT)-1,m=ceil(1.0*b.length()/DIGIT)-1;
	for (int i=0; i<=n; i++) {
		string s=a.substr(i*DIGIT,DIGIT);
		reverse(s.begin(),s.end());
		F[i].r=stoll(s);
	}
	for (int i=0; i<=m; i++) {
		string s=b.substr(i*DIGIT,DIGIT);
		reverse(s.begin(),s.end());
		G[i].r=stoll(s);
	}

	while (lim<=n+m) lim<<=1,len++;
	for (int i=0; i<lim; i++) rev[i]=(rev[i>>1]>>1)|((i&1)<<(len-1));
	FFT(F,1);
	FFT(G,1);
	for (int i=0; i<=lim; i++) {
		F[i]=F[i]*G[i];
	}
	FFT(F,-1);
	for (int i=0; i<=n+m; i++) {
		f[i]=ll(F[i].r+0.5);
	}
	int i=0;
	while (f[i]!=0 or i<=n+m) {
		if (f[i]>=BASE) {
			f[i+1]+=f[i]/BASE;
			f[i]=f[i]%BASE;
		}
		i++;
	}
	while (i--) cout<<f[i];
	return 0;
}

常量DIGIT是压位的位数 压2位在本地测试可以过样例

2022/11/12 21:41
加载中...