1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 const double PI=acos(-1); 8 const int maxn=250005; 9 int n,len,m,rev[maxn],ans[maxn]; 10 struct node{ 11 double real,imag; 12 node operator +(const node &x){return (node){real+x.real,imag+x.imag};} 13 node operator -(const node &x){return (node){real-x.real,imag-x.imag};} 14 node operator *(const node &x){return (node){real*x.real-imag*x.imag,real*x.imag+imag*x.real};} 15 }a[maxn],b[maxn],c[maxn],w,wn,t1,t2; 16 void read(int &x){ 17 x=0; int f=1; char ch; 18 for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-1; 19 for (;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; x*=f; 20 } 21 void Read(node *a){ 22 char ch; 23 for (int i=m-1;i>=0;i--){ 24 for (ch=getchar();!isdigit(ch);ch=getchar()); 25 a[i].real=(double)(ch-'0'); 26 } 27 } 28 int Rev(int x){ 29 int temp=0; 30 for (int i=0;i<len;i++) temp<<=1,temp+=(x&1),x>>=1; 31 return temp; 32 } 33 void FFT(node *a,int op){ 34 for (int i=0;i<n;i++) if (i<rev[i]) swap(a[i],a[rev[i]]); 35 for (int s=2;s<=n;s<<=1){ 36 wn=(node){cos(op*2*PI/s),sin(op*2*PI/s)}; 37 for (int i=0;i<n;i+=s){ 38 w=(node){1,0}; 39 for (int j=i;j<i+s/2;j++,w=w*wn){ 40 t1=a[j],t2=w*a[j+s/2]; 41 a[j]=t1+t2,a[j+s/2]=t1-t2; 42 } 43 } 44 } 45 } 46 int main(){ 47 read(m); n=1,len=0; 48 while (n<(m<<1)) n<<=1,len++; 49 Read(a),Read(b); 50 for (int i=0;i<n;i++) rev[i]=Rev(i); 51 FFT(a,1),FFT(b,1); 52 for (int i=0;i<n;i++) c[i]=a[i]*b[i]; 53 FFT(c,-1); 54 for (int i=0;i<n;i++) ans[i]=(int)round(c[i].real/n); 55 for (int i=0;i<n;i++) ans[i+1]+=ans[i]/10,ans[i]=ans[i]%10; 56 int j; for (j=n-1;j>=0;j--) if (ans[j]) break; 57 if (j==-1) puts("0"); 58 else{for (;j>=0;j--) printf("%d",ans[j]);puts("");} 59 return 0; 60 }
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2179
题目大意:给定两个大数a,b,求a*b,位数n<=60000;
做法:FFT入门题,FFT的做法可以自己去看算法导论,这题是裸的卷积,直接上DFT或者NTT,我贴的是DFT的。