BZOJ[3527],[ZJOI2014]力(FFT)

BZOJ[3527],[ZJOI2014]力(FFT)

  • 题意:

给出\(n\)个数\(q_i\),给出\(Fj\)的定义如下:

\(F_j=\sum \limits _ {i < j} \frac{q_iq_j}{(i-j)^2}-\sum \limits _{i >j} \frac{q_iq_j}{(i-j)^2}.\)

令\(E_i=F_i/q_i\),求\(E_i\).

  • 题解:

一开始没发现求\(E_i\)... 其实题目还更容易想了...

\(E_i=\sum\limits _{j<i}\frac{q_j}{(i-j)^2}-\sum\limits _{j>i}\frac{q_j}{(i-j)^2}\)

这个东西就是转换成求两个一样的东西就行了。

就是求\(sum_i=\sum \limits_{j<i} \frac{q_j}{(i-j)^2}\).

这个就是可以转换成求一个卷积形式就行了。

注意多项式乘法格式是这样的:

\(A_0+A_1x+...+A_nx^n\)

\(B_0+B_1x+...+B_nx^n\)

令\(A\)与\(B\)的卷积为\(C\),则\(C_i=\sum \limits _{j \le i}A_j*B_{i-j}\).

发现\(i-j\)那个形式似乎就可以满足本题的形式。

所以令\(B_i=\frac{1}{i^2}\)就行了,然后\(A_i=q_i\).

对于这个求两边卷积就行了23333

注意有的细节要处理一下,就是要清空一些数组,

注意一下下标(思维要清楚),而且也要令\(A_0=B_0=0\)。

而且之前求\(B_i\)的时候,\(i^2\)会爆long long

  • 代码:

```cpp

#include <bits/stdc++.h>

#define For(i, l, r) for(register int i = (l), end = (int)(r); i <= end; ++i)

#define Fordown(i, r, l) for(register int i = (r), end = (int)(l); i >= end; --i)

#define Set(a, v) memset(a, v, sizeof(a))

using namespace std;

bool chkmin(int &a, int b) {return b < a ? a = b, 1 : 0;}

bool chkmax(int &a, int b) {return b > a ? a = b, 1 : 0;}

inline int read() {

int x = 0, fh = 1; char ch = getchar();

for (; !isdigit(ch); ch = getchar() ) if (ch == ‘-‘) fh = -1;

for (; isdigit(ch); ch = getchar() ) x = (x<<1) + (x<<3) + (ch ^ ‘0‘);

return x * fh;

}

void File() {

#ifdef zjp_shadow

freopen ("P3527.in", "r", stdin);

freopen ("P3527.out", "w", stdout);

#endif

}

struct Complex { double re, im; };

inline Complex operator + (const Complex &lhs, const Complex &rhs) {

return (Complex) {lhs.re + rhs.re, lhs.im + rhs.im};

}

inline Complex operator - (const Complex &lhs, const Complex &rhs) {

return (Complex) {lhs.re - rhs.re, lhs.im - rhs.im};

}

inline Complex operator * (const Complex &lhs, const Complex &rhs) {

return (Complex) {lhs.re * rhs.re - lhs.im * rhs.im, lhs.re * rhs.im + rhs.re * lhs.im};

}

const int N = 1 << 19;

int n_, n;

double f[N], g[N];

const double Pi = acos(-1.0);

int r[N];

void FFT(Complex P[], int opt) {

For (i, 0, n - 1) if (i < r[i]) swap(P[i], P[r[i]]);

for (int i = 2; i <= n; i <<= 1) {

Complex Wi = (Complex) {cos(2 * Pi / i), opt * sin(2 * Pi / i)};

int p = i / 2;

for (int j = 0; j < n; j += i) {

Complex x = (Complex) {1.0, 0.0};

For (k, 0, p - 1) {

Complex u = P[j + k], v = x * P[j + k + p];

P[j + k] = u + v;

P[j + k + p] = u - v;

x = x * Wi;

}

}

}

}

int m;

void Mult(Complex a[], Complex b[]) {

int cnt = 0;

for (n = 1; n <= m; n <<= 1) ++ cnt;

For (i, 1, n - 1)

r[i] = (r[i >> 1] >> 1) | ((i & 1) << (cnt - 1) );

FFT(a, 1); FFT(b, 1);

For (i, 0, n - 1) a[i] = a[i] * b[i];

FFT(a, -1);

For (i, 0, n - 1) a[i].re = a[i].re / n;

}

double ans[N];

Complex a[N], b[N];

int main () {

File();

n_ = read();

m = n_ + n_;

For (i, 1, n_) {

scanf("%lf", &f[i]);

g[i] = (double)1.0 / ((long long)i * (long long)i);

}

For (i, 0, n_) a[i].re = f[i], a[i].im = 0;

For (i, 0, n_) b[i].re = g[i], b[i].im = 0;

Mult(a, b);

For (i, 1, n_)

ans[i] += a[i].re;

  reverse(f + 1, f + 1 + n_);
  For (i, 0, n - 1) a[i].re = f[i], a[i].im = 0;
  For (i, 0, n - 1) b[i].re = g[i], b[i].im = 0;

  Mult(a, b);

  For (i, 1, n_)
      ans[n_ - i + 1] -= a[i].re;

  For (i, 1, n_)
      printf ("%.4lf\n", ans[i]);
  return 0;

}

```

原文地址:https://www.cnblogs.com/zjp-shadow/p/8435930.html

时间: 2024-12-16 08:50:00

BZOJ[3527],[ZJOI2014]力(FFT)的相关文章

BZOJ 3527: [Zjoi2014]力 FFT

3527: [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.34

BZOJ 3527: [Zjoi2014]力 [快速傅里叶变换]

3527: [Zjoi2014]力 Time Limit: 30 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1723  Solved: 1015[Submit][Status][Discuss] Description 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. Input 第一行一个整数n. 接下来n行每行输入一个数,第i行表示qi. n≤100000,0<qi<1000000000 Output n行,第i

【BZOJ】3527: [Zjoi2014]力 FFT

[参考]「ZJOI2014」力 - FFT by menci [算法]FFT处理卷积 [题解]将式子代入后,化为Ej=Aj-Bj. Aj=Σqi*[1/(i-j)^2],i=1~j-1. 令f(i)=qi,g(i)=1/i^2,定义f(0)=g(0)=0(方便卷积). Aj=Σf(i)*g(j-i),i=0~j-1,标准的卷积形式. 而对于Bj,将g反转后就是和为i+n-1的标准卷积形式了. 第一次FFT后,记得对a数组后半部分清零后再进行第二次FFT. 复杂度O(n log n). #incl

[BZOJ 3527][Zjoi2014]力(FFT)

Description 给出n个数qi,给出Fj的定义如下: 令Ei=Fi/qi,求Ei. Solution 设fi=qi gi=1/i/i(这里如果写成i*i可能会爆int) 那前半部分就是∑fi*gj-i 发现是一个卷积的形式 后半部分把数组反一下同理 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #define

数学(FFT):BZOJ 3527 [Zjoi2014]力

题目在这里:http://wenku.baidu.com/link?url=X4j8NM14MMYo8Q7uPE7-7GjO2_TXnMFA2azEbBh4pDf7HCENM3-hPEl4mzoe2wSoblrSOvMirfS7PsQ1OVjsdaCJhEaGNCpuUxFKoPvNvXa 裸的FFT,小心i*i爆int!!! 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #includ

bzoj 3527: [Zjoi2014]力【FFT】

大力推公式,目标是转成卷积形式:\( C_i=\sum_{j=1}^{i}a_jb_{i-j} \) 首先下标从0开始存,n-- \[ F_i=\frac{\sum_{j<i}\frac{q_jq_i}{(j-i)^2}-\sum_{j>i}\frac{q_jq_i}{(j-i)^2}}{q_i} \] \[ F_i=\sum_{j<i}\frac{q_j}{(j-i)^2}-\sum_{j>i}\frac{q_j}{(j-i)^2} \] 设 \[ a_i=\sum_{j<

bzoj 3527: [Zjoi2014]力

都说这是个FFT模板题 可我这种蒟蒻还是看了大半天... 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<queue> 7 #include<algorithm> 8 #include<vector> 9 #include<complex

3527: [Zjoi2014]力 - BZOJ

题目大意:给出n个数qi,定义 Fj为 令 Ei=Fi/qi,求Ei. 看了很久题解,终于有些眉目,因为知道要用FFT,所以思路就很直了 其实我们就是要±1/(j-i)^2 ( i-j大于0时为正,小于0时为负 ) 和 qi 的乘积要算到j这个位置上,这个满足卷积,所以用FFT优化,但是j-i有负数,所以我们就加上一个n 于是设pi={ i>n,1/(i-n)^2 i<n,-1/(n-i)^2 其他,0 } 然后就套FFT模板就行了 1 const 2 maxn=800100; 3 type

[Zjoi2014]力 FFT

#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef double dd; const dd pi=acos(0.0)*2; #define N 400005 struct P{ dd x,y; P(dd A=0.0,dd B=0.0){ x=A; y=B; } P

[Zjoi2014]力(FFT/NTT)

[Zjoi2014]力(FFT,卷积) 题意:给定\(n\)个点电荷,排在单位数轴上,求每个点的场强 考虑每个\(i\)对于每个\(j\)的贡献,分析式子 \(E=\cfrac{q_i}{(j-i)^2}\) 令\(f(x)=\sum q_ix^i\) \(g(x)=\sum a_ix^i,a_i=i<0?-\frac{1}{i^2}:\frac{1}{i^2}\) \(g(x)\)每一项\(x\)的指数其实是\(j-i\)的值 求\(f(x)\cdot g(x)\)即可,注意负数系数的话偏移一