zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 2194 快速傅立叶之二

    Description

    请计算C[k]=sigma(a[i]*b[i-k]) 其中 k < = i < n ,并且有 n < = 10 ^ 5。 a,b中的元素均为小于等于100的非负整数。

    Input

    第一行一个整数N,接下来N行,第i+2..i+N-1行,每行两个数,依次表示a[i],b[i] (0 < = i < N)。

    Output

    输出N行,每行一个整数,第i行输出C[i-1]。

    Sample Input

    5
    3 1
    2 4
    1 1
    2 4
    1 4

    Sample Output

    24
    12
    10
    6
    1

    Solution

    看上去是个FFT的模板题,实际上它就是的
    将b数组翻转之后,c数组就可以用FFT求了
    手写c数组原来一些位置的式子,然后会发现它们在新的c数组的位置的规律
    输出就好了

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const db Pi=acos(-1);
    const int MAXN=1<<19;
    int n,m,cnt,rev[MAXN],sn;
    struct Complex{
    	db real,imag;
    	inline Complex operator + (const Complex &A) const {
    		return (Complex){real+A.real,imag+A.imag};
    	};
    	inline Complex operator - (const Complex &A) const {
    		return (Complex){real-A.real,imag-A.imag};
    	};
    	inline Complex operator * (const Complex &A) const {
    		return (Complex){real*A.real-imag*A.imag,imag*A.real+real*A.imag};
    	};
    };
    Complex a[MAXN],b[MAXN];
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    inline void FFT(Complex *A,int tp)
    {
    	for(register int i=0;i<n;++i)
    		if(i<rev[i])std::swap(A[i],A[rev[i]]);
    	for(register int l=2;l<=n;l<<=1)
    	{
    		Complex wn=(Complex){cos(2*Pi/l),sin(tp*2*Pi/l)};
    		for(register int i=0;i<n;i+=l)
    		{
    			Complex w=(Complex){1,0};
    			for(register int j=0;j<(l>>1);++j)
    			{
    				Complex A1=A[i+j],A2=A[i+j+(l>>1)]*w;
    				A[i+j]=A1+A2,A[i+j+(l>>1)]=A1-A2;
    				w=w*wn;
    			}
    		}
    	}
    }
    int main()
    {
    	read(n);m=n+n-1;sn=n;
    	for(register int i=0;i<n;++i)scanf("%lf%lf",&a[i].real,&b[i].real);
    	std::reverse(b,b+n);
    	for(n=1;n<m;n<<=1)++cnt;
    	for(register int i=0;i<n;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
    	FFT(a,1);FFT(b,1);
    	for(register int i=0;i<n;++i)a[i]=a[i]*b[i];
    	FFT(a,-1);
    	for(register int i=sn-1;i<=sn+sn-2;++i)write((int)(a[i].real/n+0.5),'
    ');
    	return 0;
    }
    
  • 相关阅读:
    day01--计算机硬件基础笔记
    22 Jun 18 Django,ORM
    21 Jun 18 Django,ORM
    20 Jun 18 复习, mysql
    20 Jun 18 Django,ORM
    19 Jun 18 复习, 正则表达式
    19 Jun 18 Django
    15 Jun 18 复习, shutil模块
    15 Jun 18 Django
    14 Jun 18 复习, form表单
  • 原文地址:https://www.cnblogs.com/hongyj/p/9561481.html
Copyright © 2011-2022 走看看