码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2014] 力

时间:2020-01-28 15:49:49      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:++   err   void   display   bug   卡精度   utc   fft   spl   

题目大意

给定长度为\(n\)的序列\(q_i\)
\[F_j = \sum_{i = 1}^{j - 1} \frac{q_i * q_j}{(i - j) ^ 2} - \sum_{i = j+1}^{n} \frac{q_i * q_j}{(i - j) ^ 2} \]
\[E_i = \frac {F_i}{q_i}\]
对于 \(1 \leq i \leq n\)\(E_i\)

精度为\(10^{-2}\)

正解

很明显的变形 \(F_j = q_j * (\sum_{i = 1}^{j - 1} \frac{q_i}{(i - j) ^ 2} - \sum_{i = j+1}^{n} \frac{q_i}{(i - j) ^ 2})\)
相应的 \(E_i = \sum_{i = 1}^{j - 1} \frac{q_i}{(i - j) ^ 2} - \sum_{i = j+1}^{n} \frac{q_i}{(i - j) ^ 2}\)
我们尝试用卷积的形式表示\(E_i\)
\(g(x) = \sum_{i = 1}^{i=n} \frac {1}{i*i} * x ^ i\) \(f(x) = \sum_{i=1}^{n} q_i*x^i\)
那么\(E_i = \sum_{j=1}^{i-1}f(j) * g(i-j) - \sum_{j=i+1}^{n}f(j)*g(j-i)\)
前面的式子是个很裸的卷积 后面式子 我们也尝试将它变为卷积
\(h(j) = f(n-j+1)\)
那么\(E_i = \sum_{j=1}^{i-1}f(j) * g(i-j) - \sum_{j=i+1}^{n}f(n-j+1)*g(j-i)\)
两边都是卷积 \(FFT\)就行了 \(4\)\(FFT\)被卡精度了 只好写\(5\)次了 哭唧唧

Code

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <set>
#include <map>
#include <queue>

using namespace std;

template <typename T> void chkmax(T &x, T y) {x = x > y ? x : y;}
template <typename T> void chkmin(T &x, T y) {x = x > y ? y : x;}

typedef long long ll;

const int INF = 2139062143;

#define DEBUG(x) std::cerr << #x << " = " << x << std::endl

template <typename T> void read (T &x) {
    x = 0; bool f = 1; char ch;
    do {ch = getchar(); if (ch == '-') f = 0;} while (ch > '9' || ch < '0');
    do {x = x * 10 + ch - '0'; ch = getchar();} while (ch >= '0' && ch <= '9');
    x = f ? x : -x;
}   

template <typename T> void write (T x) {
    if (x < 0) x = ~x + 1, putchar ('-');
    if (x > 9) write (x / 10);
    putchar (x % 10 + '0');
}

const long double PI = acos (-1.0);
const int N = 262144 + 5;


struct complex {
    long double x, y;
    complex (long double xx = 0.0, long double yy = 0.0) {x = xx, y = yy;}
} a[N], b[N], c[N];

complex operator * (complex a, complex b) {return complex (a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);}
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, long double b) {return complex ((long double)a.x / b, (long double)a.y / b);}

int n, r[N];

inline void FFT (complex *a, int limit, int opt) {
    for (int i = 0; i < limit; i ++ ) if (i < r[i]) swap (a[i], a[r[i]]);
    for (int i = 1; i < limit; i <<= 1) {
        complex Wn = complex (cos (PI / i), sin (PI / i) * opt);
        for (int j = 0; j < limit; j += (i << 1)) {
            complex w = complex (1, 0);
            for (int k = 0; k < i; k ++ , w = w * Wn) {
                complex p = a[j + k], q = w * a[j + k + i];
                a[j + k] = p + q; a[j + k + i] = p - q;
            }
        }
    }
    if (opt == -1) for (int i = 0; i < limit; i ++ ) a[i] = a[i] / (long double)limit;
}

inline void File () {
    read (n);
    for (int i = 0; i < n; i ++ ) scanf ("%Lf", &a[i].x), b[n - i - 1].x = a[i].x;
    for (int i = 1; i < n; i ++ ) c[i].x = (long double) 1 / i / i;

}

inline void Poly () {
    int limit = 1, l = 0; while (limit <= (n << 1)) limit <<= 1, l ++ ;
    for (int i = 0; i < limit; i ++ ) r[i] = ((r[i >> 1] >> 1) | ((i & 1) << (l - 1)));
    FFT (a, limit, 1); FFT (b, limit, 1); FFT (c, limit, 1);
    for (int i = 0; i < limit; i ++ ) a[i] = a[i] * c[i], b[i] = b[i] * c[i];
    FFT (a, limit, -1); FFT (b, limit, -1);
}

inline void Print () {
    for (int i = 0; i < n; i ++ ) printf ("%.10Lf\n", (long double) a[i].x - b[n - i - 1].x);
}

int main() {
    File ();
    Poly ();
    Print ();
    return 0;
}

[ZJOI2014] 力

标签:++   err   void   display   bug   卡精度   utc   fft   spl   

原文地址:https://www.cnblogs.com/Hock/p/12238065.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!