题意;求两个数相乘。
第一次写非递归的fft,因为一个数组开小了调了两天TAT。
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> using namespace std; #define PI 3.1415926535897932384 #define MAXN 1200000 #pragma optimize("O2") struct Complex { double x,y; Complex(){}; Complex(double x,double y):x(x),y(y){}; void init(double x,double y) { this->x=x;this->y=y; } Complex operator +(Complex a) { Complex ret(x + a.x, y + a.y); return ret; } Complex operator -(Complex a) { Complex ret(x - a.x, y - a.y); return ret; } Complex operator *(Complex a) { Complex ret(x*a.x - y*a.y, x*a.y + y*a.x); return ret; } Complex operator /(double v) { Complex ret(x/v,y/v); return ret; } Complex operator =(double x) { this->x=x; return *this; } void operator -=(Complex a) { this->x-=a.x; this->y-=a.y; } void operator +=(Complex a) { this->x+=a.x; this->y+=a.y; } }; char ss[MAXN]; int t1[MAXN],t2[MAXN]; int pp[MAXN]; Complex ww[MAXN][2]; Complex g1[MAXN],g2[MAXN]; long long res[MAXN]; int n; void dft(Complex g[],int len,int sign) { Complex t; for (int i=1;i<len;i<<=1) { for (int j=0;j<len;j+=(i<<1)) { for (int k=0;k<i;k++) { t=g[j+k]; g[j+k]=g[j+k]+g[j+k+i]*ww[k*((n>>1)/i)][sign]; g[j+k+i]=t-g[j+k+i]*ww[k*((n>>1)/i)][sign]; } } } } int main() { freopen("input.txt","r",stdin); // freopen("output.txt","w",stdout); int i,j,k,x,y,z,m; int n1,n2; int nn; scanf("%d",&nn); while (nn--) { scanf("%s",ss); m=strlen(ss); for (i=0;i<m;i++) t1[(m-i-1)/5]=t1[(m-i-1)/5]*10+ss[i]-‘0‘; n1=(m-1)/5+1; scanf("%s",ss); m=strlen(ss); for (i=0;i<m;i++) t2[(m-i-1)/5]=t2[(m-i-1)/5]*10+ss[i]-‘0‘; n2=(m-1)/5+1; n=max(n1,n2); while (n!=(n&(-n)))n-=n&(-n); n<<=2; for (i=0;i<n;i++) for (j=n>>1,x=1;j;j>>=1,x<<=1) if (i&j)pp[i]+=x; for (i=0;i<n1;i++)g1[pp[i]].x=t1[i]; for (i=0;i<n2;i++)g2[pp[i]].x=t2[i]; for (i=0;i<=n;i++) { ww[i][0].init(cos(2*PI*i/n), -sin(2*PI*i/n)); ww[i][1].x=ww[i][0].x; ww[i][1].y=-ww[i][0].y; } dft(g1,n,0); dft(g2,n,0); for (i=0;i<n;i++)g2[i]=g1[i]*g2[i]; for (i=0;i<n;i++)g1[pp[i]]=g2[i]; dft(g1,n,1); for (i=0;i<n;i++)res[i]=(long long)(g1[i].x/n+0.5); for (i=0;i<n;i++)res[i+1]+=res[i]/100000,res[i]%=100000; m=n; while (m && !res[m-1])m--; printf("%d",(int)res[m-1]); for (i=m-2;i>=0;i--) printf("%05d",(int)res[i]); printf("\n"); memset(t1,0,sizeof(t1[0])*n); memset(t2,0,sizeof(t2[0])*n); memset(pp,0,sizeof(pp[0])*n); memset(res,0,sizeof(res[0])*n); memset(g1,0,sizeof(g1[0])*n); memset(g2,0,sizeof(g2[0])*n); } }
时间: 2024-11-09 19:06:51