• 【刷题】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;
    }
    
  • 相关阅读:
    Spark架构分析
    mr运行出错,解决办法
    hbase调优
    虚拟机长时间不关造成的问题
    crontab 使用
    虚拟机克隆网络问题的解决
    ligerui.grid.extend.rowSpan
    64位下安装Scrapy 报错 "could not find openssl.exe" 的解决方法。
    EventBus 事件总线之我的理解
    MongoDB 系列(二) C# 内嵌元素操作 聚合使用
  • 原文地址:https://www.cnblogs.com/hongyj/p/9561481.html
Copyright © 2020-2023  润新知