FFT bzoj2179: FFT快速傅立叶

一个晚上和FFT相爱相杀的故事。。。。。。

反正就是裸的。。。。

然后这个是递归式的 自己还是太弱了。。。。

话说发现自己的代码很长诶。。。。。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const double PI=acos(-1);
struct Complex
{
	double Real,fake;
	Complex(){Real=fake=0;	}
	Complex(double r,double f){Real=r,fake=f;	}
	inline friend Complex operator *(Complex a,Complex b)
	{return (Complex){a.Real*b.Real-a.fake*b.fake,a.fake*b.Real+a.Real*b.fake};}
	inline friend Complex operator +(Complex a,Complex b)
	{return (Complex){a.Real+b.Real,a.fake+b.fake};}
	inline friend Complex operator -(Complex a,Complex b)
	{return (Complex){a.Real-b.Real,a.fake-b.fake};}
	inline friend Complex operator -(Complex a,double b)
	{return (Complex){a.Real-b,a.fake};}
	inline friend Complex operator -(double a,Complex b)
	{return (Complex){a-b.Real,0-b.fake};}
	inline friend Complex operator *(double a,Complex b)
	{return (Complex){a*b.Real,a*b.fake};}
	inline friend Complex operator *(Complex a,double b)
	{return (Complex){b*a.Real,b*a.fake};}
	
};
Complex W;	
int base=1;
char c;
inline void read(int &a)
{	a=0;do c=getchar();while(c<'0'||c>'9');	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();}

struct Complex_Line
{
	Complex *data; 
   int len;
   
   inline void build(int a){
   data=new Complex[a];
   len=a;}
}a[1001];

Complex_Line DFT(Complex_Line Tp,int len,int on)
{
     if(len==1)return Tp;
     Complex_Line a1,a2,y;
     Complex W=(Complex){cos(2*PI/len),sin(-on*2*PI/len)};
     y.build(len);
     a1.build(len>>1);
     a2.build(len>>1);
     for(int i=1;i<=len>>1;i++)
        a1.data[i-1]=Tp.data[(i<<1)-2],a2.data[i-1]=Tp.data[(i<<1)-1];
     a1=DFT(a1,len>>1,on),
	 a2=DFT(a2,len>>1,on);
     Complex w=(Complex){1,0}; 
	 for(int i=1;i<=len>>1;i++)
       y.data[i-1]=a1.data[i-1]+a2.data[i-1]*w,
       y.data[i-1+(len>>1)]=a1.data[i-1]-a2.data[i-1]*w,
	   w=w*W;
	return y;
}
	int sum[1000001];
char s1[100001],s2[100001];
int main()
{

    int len1,len2;
    int n;
    read(n);
    Complex_Line a,b;		
	scanf("%s",s1);		
	scanf("%s",s2);
	len1=strlen(s1),len2=strlen(s2);
	
	while(base<n)base<<=1;
	base<<=1;
	a.build(base);
	b.build(base);
	W=(Complex){cos(2*PI/base),sin(2*PI/base)};
	for(int i=0;i<len1;i++)
	 a.data[i]=(Complex){s1[len1-i-1]-'0',0};
	for(int i=len1;i<base;i++)
	 a.data[i]=(Complex){0,0};
	for(int i=0;i<len2;i++)
	 b.data[i]=(Complex){s2[len2-i-1]-'0',0};
	for(int i=len2;i<base;i++)
	 b.data[i]=(Complex){0,0};
	a=DFT(a,base,1);
	b=DFT(b,base,1);
	for(int i=1;i<=base;i++)
	   a.data[i-1]=a.data[i-1]*b.data[i-1];
    a=DFT(a,base,-1);
	for(int i=0;i<base;i++)
            a.data[i].Real/=base;
	memset(sum,0,sizeof(sum));
    int len3=len2+len1;
    for(int i=0;i<base;i++)
       sum[i]=(int){a.data[i].Real+0.5};
	for(int i=0;i<len3;i++)
	    sum[i+1]+=sum[i]/10,sum[i]%=10;
	while(!sum[len3])len3--;
	for(int i=len3;i!=-1;i--)
	   putchar('0'+sum[i]);
	  putchar('\n'); 
	return 0;
} 

1/22/2016

去黄学长哪里学了一下Rader  还有c++自带的complex。。

感觉那个Rader很叼的样子

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<complex> 
using namespace std;
 
#define com complex<double> 
char c;
inline void read(int &a)
{
	a=0;do c=getchar();while(c<'0'||c>'9');
	while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();
}
inline void Get(int &a)
{
	a=0;do c=getchar();while(c<'0'||c>'9');
    a=c-'0';
}
int St[1000001];
struct Complex_Line
{
	int n;
	com *Line;
	inline void Begin(int t){Line=new com[n=t];}
    inline void print()
    {
    	for(int i=0;i<n;i++)
	   St[i]=(Line[i].real()+0.1);
       St[n]=0;
	   for(int i=0;i<n;i++)
		{	
		   St[i+1]+=St[i]/10,
		   St[i]%=10;
	        if(St[i]<0)St[i+1]--,St[i]+=10;
		 }
		int len=n;
		if(St[len+1])len++;
		while(!St[len])len--;
		printf("%d",St[len]);
		while(len--)
		   putchar('0'+St[len]);
    	 
	}
};
const
  double pi=acos(-1);
int rev[1000001];
inline void  Beg(int Len)
{
  int L=0,t=1;
  while((1<<L)^Len)L++;
  for(int i=0;i<Len;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(L-1));
}
inline Complex_Line Rev(Complex_Line a)
{
	Complex_Line Re;
	Re.Begin(a.n);
	for(int i=0;i<a.n;i++)
	  Re.Line[rev[i]]=a.Line[i];
	return Re;
}

inline Complex_Line FFT(Complex_Line t,int f)
{
	int n=t.n;
	Complex_Line A=Rev(t);
	for(int i=1;i<n;i<<=1)
	  {
	  	com W0=com(cos(pi/i),f*sin(pi/i));
	  	for(int j=0;j<n;j+=(i<<1))
          {
          	com W(1,0);
          	for(int k=0;k<i;k++)
              {
              	com x=A.Line[j+k],y=W*A.Line[j+k+i];
                A.Line[j+k]=x+y;
                A.Line[j+k+i]=x-y;
                W*=W0;
			  }
		  }
	
	  }	
	  if(f==-1)
		   for(int j=0;j<n;j++)
		    A.Line[j]/=n;
	return A;
}

int main()
{
	int n;
	read(n);
	int tp=n;
	while(tp^(tp&-tp))
	{
		tp^=tp&-tp;
	}
		tp<<=2;
	int i;
	Complex_Line A,B;
	A.Begin(tp);
	B.Begin(tp);
	int j;
    for(i=1;i<=n;i++)
      {
	  Get(j);
	  A.Line[n-i]=j;
      }
	for(i=n;i<tp;i++)
     A.Line[i]=com(0,0);     
    for(i=1;i<=n;i++)
      Get(j),B.Line[n-i]=j;
    for(i=n;i<tp;i++)
     B.Line[i]=com(0,0);
     Beg(tp);
	A=FFT(A,1);
	B=FFT(B,1);
	for(i=0;i<tp;i++)
	 A.Line[i]=A.Line[i]*B.Line[i];
	A=FFT(A,-1);
	A.print();
	return 0;
} 


你可能感兴趣的:(fft,bzoj)