zoukankan      html  css  js  c++  java
  • BZOJ3257 [Zjoi2014]力 多项式 FFT

    原文链接http://www.cnblogs.com/zhouzhendong/p/8762639.html

    题目传送门 - BZOJ3527

    题意

      给出长度为$m$的序列$q_{1..m}$,让你输出长度为$m$的序列$E_{1..m}$。

      其中:

      $$E_i=sum_{j=1}^{i-1}frac{q_j}{(i-j)^2}-sum_{j=i+1}^{m}frac{q_j}{(i-j)^2}$$

    题解

      我们设

      $$f_i=q_i,g_i=frac 1{i^2}(g_0=0,且对于i>m,g_i=0),f_i^r=f_{m-i}$$

      于是:

      $$E_i=sum_{j=0}^i f_jg_{i-j}-sum_{j=i}^m f_jg_{j-i}$$

      这个式子的前一半是个裸的卷积,可以直接$FFT$。后一半要稍微变变。(有dalao说是两个裸的卷积!Orz)

      $$sum_{j=i}^m f_{j}g_{j-i}\=sum_{j=i}^{m}f_{m-j}^rg_{i-j}\=sum_{j=0}^{m-i}f_{m-i-j}^rg_{j}$$

      令$i'=m-i$,则:

      $$sum_{j=0}^{m-i}f_{m-i-j}^rg_{j}\=sum_{j=0}^{i'}f_{i'-j}^rg_{j}\=sum_{j=0}^{i'}f_{j}^rg_{i'-j}$$

      于是也是一个裸的卷积形式了。

      但是这题我做了很久。QAQ。

      一开始把$m$和$n$搞错,而且还很自信的认为是等价的。($n$见代码)

      然后发现$IDFT$之后忘记把数字除以$n$了。

      然后还是挂了。

      然后看(%)了看(%)网上AC的代码,发现我和他唯一的区别就是他把$i>m$的$g_i$都搞成$0$,而我没搞,但是我仍然很自信的认为是对的QAQ。

      最后把我的自信全部打翻,然后就突然A掉了QAQ。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N=1<<19;
    int m,n,L,R[N];
    double q[N],PI=acos(-1.0);
    struct C{
    	double r,i;
    	C(){}
    	C(double a,double b){r=a,i=b;}
    	C operator + (C x){return C(r+x.r,i+x.i);}
    	C operator - (C x){return C(r-x.r,i-x.i);}
    	C operator * (C x){return C(r*x.r-i*x.i,i*x.r+r*x.i);}
    }A[N],B[N],ans1[N],ans2[N],w[N];
    void FFT(C a[]){
    	for (int i=0;i<n;i++)
    		if (i<R[i])
    			swap(a[i],a[R[i]]);
    	for (int d=1,t=n>>1;d<n;d<<=1,t>>=1)
    		for (int i=0;i<n;i+=(d<<1))
    			for (int j=0;j<d;j++){
    				C tmp=w[t*j]*a[i+j+d];
    				a[i+j+d]=a[i+j]-tmp;
    				a[i+j]=a[i+j]+tmp;
    			}
    }
    void FFT_times(C A[],C B[],C C[]){
    	FFT(A),FFT(B);
    	for (int i=0;i<n;i++)
    		w[i].i*=-1.0,C[i]=A[i]*B[i];
    	FFT(C);
    	for (int i=0;i<n;i++)
    		w[i].i*=-1.0,C[i].r/=n;
    }
    int main(){
    	scanf("%d",&m);
    	for (int i=1;i<=m;i++)
    		scanf("%lf",&q[i]);
    	for (n=1,L=0;n<m*2;n<<=1,L++);
    	for (int i=0;i<n;i++){
    		w[i]=C(cos(2*i*PI/n),sin(2*i*PI/n));
    		R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
    		A[i]=C(q[i],0);
    		B[i]=C((i==0||i>m)?0:1.0/i/i,0);
    	}
    	FFT_times(A,B,ans1);
    	for (int i=0;i<n;i++){
    		A[i]=C(i<=m?q[m-i]:0,0);
    		B[i]=C((i==0||i>m)?0:1.0/i/i,0);
    	}
    	FFT_times(A,B,ans2);
    	for (int i=1;i<=m;i++)
    		printf("%.3lf
    ",ans1[i].r-ans2[m-i].r);
    	return 0;
    }
    

      

  • 相关阅读:
    改写历史,永久删除git库的物理文件
    双调排序
    GitHub从无到有
    Nginx的安装与基本应用
    Django从无到有的艰苦历程
    pycharm 相关设置问题
    ORM介绍
    Django中的过滤器
    FBV和CBV的差异
    django中models field详解
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/BZOJ3527.html
Copyright © 2011-2022 走看看