zoukankan      html  css  js  c++  java
  • 【BZOJ3527】[Zjoi2014]力 FFT

    【BZOJ3527】[Zjoi2014]力

    Description

    给出n个数qi,给出Fj的定义如下:
    令Ei=Fi/qi,求Ei.

    Input

    第一行一个整数n。
    接下来n行每行输入一个数,第i行表示qi。
    n≤100000,0<qi<1000000000

    Output

     n行,第i行输出Ei。与标准答案误差不超过1e-2即可。

    Sample Input

    5
    4006373.885184
    15375036.435759
    1717456.469144
    8514941.004912
    1410681.345880

    Sample Output

    -16838672.693
    3439.793
    7509018.566
    4595686.886
    10903040.872

    题解:对于上面的式子,我们将i<j和i>j分开计算

    (感觉并没有推什么)

    然后上面那个本身就是一个卷积,下面那个跟快速傅里叶之二一样,反转过来也是一个卷积,用FFT算出来后相减即可

    #include <iostream>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #define pi acos(-1.0)
    #define z z
    using namespace std;
    struct cp
    {
    	double x,y;
    	cp (double a,double b){x=a,y=b;	}
    	cp (){}
    	cp operator + (cp a){return cp(x+a.x,y+a.y);}
    	cp operator - (cp a){return cp(x-a.x,y-a.y);}
    	cp operator * (cp a){return cp(x*a.x-y*a.y,x*a.y+y*a.x);}
    }n1[1<<20],n2[1<<20];
    double q[1<<20],a1[1<<20],a2[1<<20];
    int n;
    void init(cp *a,int len)
    {
    	int i,j,t=0;
    	for(i=0;i<len;i++)
    	{
    		if(i>t)	swap(a[i],a[t]);
    		for(j=(len>>1);(t^=j)<j;j>>=1);
    	}
    }
    void FFT(cp *a,int len,int f)
    {
    	init(a,len);
    	int i,j,k,h;
    	cp t;
    	for(h=2;h<=len;h<<=1)
    	{
    		cp wn=cp(cos(f*2*pi/h),sin(f*2*pi/h));
    		for(j=0;j<len;j+=h)
    		{
    			cp w(1,0);
    			for(k=j;k<j+h/2;k++)
    				t=w*a[k+h/2],a[k+h/2]=a[k]-t,a[k]=a[k]+t,w=w*wn;
    		}
    	}
    }
    void work(cp *a,cp *b,double *c,int len)
    {
    	FFT(a,len,1),FFT(b,len,1);
    	for(int i=0;i<len;i++)	a[i]=a[i]*b[i];
    	FFT(a,len,-1);
    	for(int i=0;i<len;i++)	c[i]=a[i].x/len;
    }
    int main()
    {
    	scanf("%d",&n);
    	int i,j,len=1;
    	while(len<2*n)	len<<=1;
    	for(i=0;i<n;i++)	scanf("%lf",&q[i]);
    	for(i=0;i<n;i++)	n1[i]=cp(q[i],0.0),n2[i]=cp(1.0/(i+1)/(i+1),0.0);
    	for(i=n;i<len;i++)	n1[i]=cp(0.0,0.0),n2[i]=cp(0.0,0.0);
    	work(n1,n2,a1,len);
    	for(i=0;i<n;i++)	n1[i]=cp(q[n-i-1],0.0),n2[i]=cp(1.0/(i+1)/(i+1),0.0);
    	for(i=n;i<len;i++)	n1[i]=cp(0.0,0.0),n2[i]=cp(0.0,0.0);
    	work(n1,n2,a2,len);
    	printf("%.3f
    ",-a2[n-2]);
    	for(i=1;i<n-1;i++)	printf("%.3f
    ",a1[i-1]-a2[n-i-2]);
    	printf("%.3f
    ",a1[n-2]);
    	return 0;
    }
  • 相关阅读:
    JavaScript 进阶篇的学习~
    JavaScript 基础的复习~
    JVM字节码解析
    Tomcat压力测试与优化方案
    Tomcat优化
    JVM垃圾收集器
    JVM的垃圾回收机制(GC)
    JVisual VM工具使用
    jstack监控JVM线程的运行情况
    监控JVM内存使用情况
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/6878518.html
Copyright © 2011-2022 走看看