BZOJ3527【FFT】

/* I will wait for you*/  
  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <cmath>  
#include <ctime>  
#include <algorithm>  
#include <iostream>  
#include <fstream>  
#include <vector>  
#include <queue>  
#include <deque>  
#include <map>  
#include <set>  
#include <string>  
#define make make_pair  
#define fi first  
#define se second  
  
using namespace std;  
  
typedef long long ll;  
typedef unsigned long long ull;  
typedef pair<int,int> pii;  
  
const int maxn = 1000010;  
const int maxm = 1010;  
const int maxs = 30;  
const int inf = 0x3f3f3f3f;  
const int P = 1000000007;  
const double error = 1e-9;  
const double Pi = 3.141592653589793238462643383279;
  
inline int read()  
{  
    int x = 0, f = 1; char ch = getchar();  
    while (ch <= 47 || ch >= 58)  
        f = (ch == 45 ? -1 : 1), ch = getchar();  
    while (ch >= 48 && ch <= 57)  
        x = x * 10 + ch - 48, ch = getchar();  
    return x * f;
}  

struct complex
{
	double re, im;
} f[maxn], g[maxn], w[2][maxn];

complex operator + (complex a, complex b)
{
	return (complex) {a.re + b.re, a.im + b.im};
}

complex operator - (complex a, complex b)
{
	return (complex) {a.re - b.re, a.im - b.im};
}

complex operator * (complex a, complex b)
{
	return (complex) {a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re};
}

int n, m, rev[maxn]; double a[maxn], b[maxn], c[maxn];

void init()
{
	for (int i = 0; i < n; i++)
		for (int j = 1, t = i; j < n; j <<= 1, t >>= 1)
			(rev[i] <<= 1) |= (t & 1);
	for (int i = 0; i < n; i++) {
		w[0][i] = (complex) {cos(2 * Pi * i / n), sin(2 * Pi * i / n)};
		w[1][i] = (complex) {cos(2 * Pi * i / n), -sin(2 * Pi * i / n)};
	}
}

void fft(complex* a, int f)
{
	for (int i = 0; i < n; i++)
		if (rev[i] > i) swap(a[i], a[rev[i]]);
	for (int i = 1; i < n; i <<= 1)
		for (int j = 0, l = n / (i << 1); j < n; j += (i << 1))
			for (int k = 0, t = 0; k < i; k++, t += l) {
				complex x = a[j + k], y = w[f][t] * a[i + j + k];
				a[j + k] = x + y, a[i + j + k] = x - y;
			}
	if (f) for (int i = 0; i < n; a[i++].re /= n);
}

int main()
{
	m = read(), n = 1 << 18, init();
	for (int i = 0; i < m; i++) scanf("%lf", &a[i]);
	for (int i = 1; i < m; i++) b[i] = 1.0 / i / i;

	for (int i = 0; i < n; i++) f[i] = g[i] = (complex) {0, 0};
	for (int i = 0; i < m; i++) {
		f[i].re = a[i], f[i].im = 0;
		g[i].re = b[i], g[i].im = 0;
	}
	fft(f, 0), fft(g, 0);
	for (int i = 0; i < n; i++) f[i] = f[i] * g[i];
	fft(f, 1);
	for (int i = 0; i < m; i++) c[i] += f[i].re;

	for (int i = 0; i < n; i++) f[i] = g[i] = (complex) {0, 0};
	for (int i = 0; i < m; i++) {
		f[i].re = a[m - 1 - i], f[i].im = 0;
		g[i].re = b[i], g[i].im = 0;
	}
	fft(f, 0), fft(g, 0);
	for (int i = 0; i < n; i++) f[i] = f[i] * g[i];
	fft(f, 1);
	for (int i = 0; i < m; i++) c[i] -= f[m - i - 1].re;

	for (int i = 0; i < m; i++) printf("%.3lf\n", c[i]);

	return 0;
}

你可能感兴趣的:(BZOJ3527【FFT】)