zoukankan      html  css  js  c++  java
  • 【BZOJ3527】【ZJOI2014】—力(FFT)

    传送门

    这题简单到我这种菜鸡都能A

    把两个式子分开考虑

    前一半就是
    ansi=j=1i1qj(ij)2ans_i=sum_{j=1}^{i-1}frac{q_j}{(i-j)^2}
    f[i]=1i2f[i]=frac 1{i^2}
    ansi=j=1i1qjfijans_i=sum_{j=1}^{i-1}q_jf_{i-j}
    发现这是一个卷积的形式,直接上fftfft就是了

    后一半把qq反过来就一样了

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define double long double
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100005;
    const double pi=acos(-1);
    double ans0[N],ans1[N],q[N];
    struct plx{
    	double x,y;
    	plx(double _x=0,double _y=0):x(_x),y(_y){}
    	friend inline plx operator +(const plx &a,const plx &b){
    		return plx(a.x+b.x,a.y+b.y);
    	}
    	friend inline plx operator -(const plx &a,const plx &b){
    		return plx(a.x-b.x,a.y-b.y);
    	}
    	friend inline plx operator *(const plx &a,const plx &b){
    		return plx(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);
    	}
    }a[N<<2],b[N<<2];
    int rev[N<<2],lim=1,tim=0;
    inline void fft(plx f[],int kd){
    	for(int i=0;i<lim;i++)if(i<rev[i])swap(f[i],f[rev[i]]);
    	for(int mid=1;mid<lim;mid<<=1){
    		plx now=plx(cos(pi/mid),kd*sin(pi/mid));
    		for(int i=0;i<lim;i+=(mid<<1)){
    			plx w=plx(1,0);
    			for(int j=0;j<mid;j++,w=w*now){
    				plx a0=f[i+j],a1=w*f[i+j+mid];
    				f[i+j]=a0+a1,f[i+j+mid]=a0-a1;
    			}	
    		}
    	}
    	if(kd==-1)for(int i=0;i<lim;i++)f[i].x/=1.0*lim;
    }
    int n;
    int main(){
    	n=read();
    	for(int i=1;i<=n;i++)scanf("%Lf",&q[i]);
    	a[0].x=0,a[0].y=0;
    	while(lim<=n*2)lim<<=1,tim++;
    	for(int i=1;i<=n;i++)a[i].x=q[i];
    	for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(tim-1));
    	for(int i=1;i<=n;i++)b[i].x=1/(1.0*i)/(1.0*i);
    	fft(a,1),fft(b,1);
    	for(int i=0;i<lim;i++)a[i]=a[i]*b[i];
    	fft(a,-1);
    	for(int i=1;i<=n;i++)ans0[i]=a[i].x;
    	for(int i=0;i<lim;i++)a[i].x=b[i].x=a[i].y=b[i].y=0;
    	for(int i=1;i<=n;i++)a[i].x=q[n-i+1];
    	for(int i=1;i<=n;i++)b[i].x=1/(1.0*i)/(1.0*i);
    	fft(a,1),fft(b,1);
    	for(int i=0;i<lim;i++)a[i]=a[i]*b[i];
    	fft(a,-1);
    	for(int i=1;i<=n;i++)ans1[n-i+1]=a[i].x;
    	for(int i=1;i<=n;i++)printf("%.6Lf
    ",ans0[i]-ans1[i]);
    }
    
  • 相关阅读:
    看某视频开始做LINUX笔记的第一天
    shell作业01
    学习shell的第一天
    学python的第三天
    【安全】573- 大前端网络安全精简指南手册
    【JS】572- JS 经典实例收集整理
    【Vuejs】571- Vue 虚拟DOM和Diff算法源码解析
    【JS】570- 揭开 JavaScript 引擎的面纱
    【JS】569- 如何避免这4类 JavaScript 内存泄漏?
    【拓展】如何在Gihub上面精准搜索开源项目?
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145611.html
Copyright © 2011-2022 走看看