题目链接:

https://www.luogu.org/problemnew/show/P3338

题目:

给出$n$个数$q_i$,令$F_j=\sum_{i<j}\frac{q_iq_j}{(i-j)^2}-\sum_{i>j}\frac{q_iq_j}{(i-j)^2}$,$E_i=\frac{F_i}{q_i}$,求$E_i$

题解:

显然$E_j=\sum_{i=1}^{j-1}\frac{q_i}{(i-j)^2}-\sum_{i=j+1}^{n}\frac{q_i}{(i-j)^2}$

不妨设$G_i=\frac{1}{i^2},G_0=0$,$T_i=q_i,T_0=0$

那么$E_j=\sum_{i=1}^{j-1}T_iG_{i-j}-\sum_{i=j+1}^{n}T_iG_{i-j}$

=$\sum_{i=0}^{j}T_iG_{i-j}-\sum_{i=j+1}^{n}T_iG_{i-j}$

显然减号前的部分是一个卷积的形式,是把$T​$和$G​$卷起来的第$i​$项

设$W_i=T_{n-i+1}(1<=i<=n),W_0=0$

减号后的$=\sum_{i=j+1}^nW_{n-i+1}G_{i-j}$

$=\sum_{i=1}^{n-j}W_iG_{n+1-i-j}$

=$\sum_{i=0}^{n-j+1}W_iG_{n+1-i-j}$

这显然也是一个卷积的形式,是把$W$和$G$卷起来的第$n+1-j$项

$E_j=\sum_{i=0}^{j}T_iG_{i-j}-\sum_{i=0}^{n-j+1}W_iG_{n+1-i-j}$

代码:

#include<algorithm>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
typedef double db; const int N=4e5+;
const double pi=acos(-1.0);
struct complex
{
double x,y;
complex (double xx=,double yy=) {x=xx;y=yy;}
}A[N],B[N];
complex operator + (complex a,complex b) {return complex(a.x+b.x,a.y+b.y);}
complex operator - (complex a,complex b) {return complex(a.x-b.x,a.y-b.y);}
complex operator * (complex a,complex b) {return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
int n;
int r[N<<];
void fft(int limit,complex *a,int type)
{
for (int i=;i<limit;i++) if (i<r[i]) swap(a[i],a[r[i]]);
for (int len=;len<limit;len<<=)
{
complex wn=complex(cos(pi/len),type*sin(pi/len));
for (int k=;k<limit;k+=(len<<))
{
complex w=complex(,);
for (int l=;l<len;l++,w=w*wn)
{
complex Nx=a[k+l],Ny=w*a[k+l+len];
a[k+l]=Nx+Ny;
a[k+l+len]=Nx-Ny;
}
}
}
}
void work(db *a,db *b,db *c)
{
int limit=,l=;
while (limit<n+n) limit<<=,++l;
for (int i=;i<=limit;i++) r[i]=(r[i>>]>>)|((i&)<<(l-));
for (int i=;i<=limit;i++) A[i].x=a[i],B[i].x=b[i],A[i].y=,B[i].y=;
fft(limit,A,);fft(limit,B,);
for (int i=;i<=limit;i++) A[i]=A[i]*B[i];
fft(limit,A,-);
for (int i=;i<=limit;i++) c[i]=A[i].x/limit;
}
db q[N],p[N],f[N],a[N],b[N];
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++)
{
scanf("%lf",&q[i]);
p[i]=q[i];
f[i]=(db)(1.0/i/i);
}
reverse(p+,p++n);
f[]=;q[]=;p[]=;
work(q,f,a);
work(p,f,b);
for (int i=;i<=n;i++) printf("%lf\n",a[i]-b[n-i+]);
return ;
}

最新文章

  1. Oracle数据库的 增、删、改、查
  2. AngularJS入门教程1--配置环境
  3. Jenkins_获取源码编译并启动服务(一)
  4. Code笔记 之:防盗链(图片)
  5. Github两步认证
  6. C#语法基础和面向对象编程
  7. Android UI学习 - GridView和ImageView的使用
  8. Java基础知识强化之集合框架笔记27:ArrayList集合练习之去除ArrayList集合中的重复字符串元素
  9. 『重构--改善既有代码的设计』读书笔记----Move Method
  10. QWidget 键盘事件 焦点(源代码级别研究)
  11. ARM裸机开发中内存管理库RT_HEAP的使用
  12. seajs源码阅读
  13. redis在Linux上的安装和简单使用
  14. [经验分享] OSCP 渗透测试认证
  15. 关于php下的ajax赋值传值的调试
  16. php实现遍历目录
  17. 【ES6】=&gt;含义
  18. centos7环境安装rabbitMQ
  19. Linux中Postfix虚拟用户及虚拟域(六)
  20. Go语言中cannot convert adminname (type interface {}) to type *: need type assertion的解决办法

热门文章

  1. 信息安全-加密:SM4.0
  2. java1.8对集合中对象的特有属性进行排序
  3. jQuery进度条设置
  4. IIS之虚拟目录学习
  5. OAuth2建立webapi认证服务供自己的客户端使用--密码模式
  6. Python写99乘法表
  7. QA小课堂:一个网站或者APP开发要多少钱
  8. Unity 设置2台摄像机的叠加
  9. 汇编(assembling)简介(源:阮一峰)
  10. python之类与对象的属性