BZOJ2194: 快速傅立叶之二

颓了那么多天开始做题目。。

今天又去看了一下FFT 总算是全部搞懂了。。

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];

int N;
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;
		int len=n;
		if(St[len+1])len++;
		while(!St[len])len--;
		for(int i=N-1;i!=-1;i--)
		printf("%d\n",St[i]);
    	 
	}
};
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);	N=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++)
      {
	  read(j);
	  A.Line[n-i]=j;
	  read(j);
	  B.Line[i-1]=j;
      }
	for(i=n;i<tp;i++)
     A.Line[i]=com(0,0),     
     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;
} 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值