zoukankan      html  css  js  c++  java
  • 洛谷 [P3338] 力

    FFT

    [E_i = F_i / q_i = sum_{i<j} frac {q_j} {(i - j)^2} - sum _{ i > j} frac{q _ j} {(i - j)^2} ]

    (p _ i = q_{n - i}) (g(i) = frac 1 {i^2})

    (E_i = sum_{j=1}^{i-1} q _ i g(j - i) - sum _ {j = i + 1} ^ n q_j g(i - j))

    (E_i = sum_{j=1}^{i-1} q_i g(i-1) - sum_{j=1}^{n - i} p_i g(i - j))

    我们发现这是一个卷积的形式, 可以用 FFT 处理

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int MAXN = 400005;
    const double PI = acos(-1);
    struct Complex {
    	double x, y;
    	Complex(double xx = 0.0, double yy = 0.0) {
    		x = xx; y = yy;
    	}
    	Complex operator + (const Complex &u) const {
    		return Complex(x + u.x, y + u.y);
    	}
    	Complex operator - (const Complex &u) const {
    		return Complex(x - u.x, y - u.y);
    	}
    	Complex operator * (const Complex &u) const{
    		return Complex(x * u.x - y * u.y, x * u.y + y * u.x);
    	}
    }a[MAXN], b[MAXN], c[MAXN], buf[MAXN];
    int n, lim = 1, limcnt, rev[MAXN];
    void fft(Complex a[], int opt) {
    	for(int i = 0; i <= lim; i++) {
    		if(i < rev[i]) swap(a[i], a[rev[i]]);
    	}
    	for(int mid = 1; mid < lim; mid <<= 1) {
    		Complex wn = Complex(cos(PI / mid), opt * sin(PI / mid));
    		for(int R = mid << 1, j = 0; j < lim; j += R) {
    			Complex w = Complex(1.0, 0.0);
    			for(int k = 0; k < mid; k++) {
    				Complex x = a[j + k], y = w * a[j + mid + k];
    				a[j + k] = x + y;
    				a[j + mid + k] = x - y;
    				w = w * wn;
    			}
    		}
    	}
    	if(opt == -1) {
    		for(int i = 0; i <= lim; i++) a[i].x = a[i].x / lim;
    	}
    }
    int main() {
    	cin >> n;
    	for(int i = 1; i <= n; i++) {
    		scanf("%lf", &a[i].x);
    		b[n - i].x = a[i].x;
    		c[i].x = (1.0 / (double)i) / (double)i;
    	}
    	while(lim <= (n << 1)) lim <<= 1, limcnt++;
     	for(int i = 0; i <= lim; i++) {
     		rev[i] = (rev[i>>1]>>1) | ((i&1)<<(limcnt - 1));
     	}
     	fft(a, 1);fft(b, 1); fft(c, 1);
     	for(int i = 0; i <= lim; i++) a[i] = a[i] * c[i];
     	for(int i = 0; i <= lim; i++) b[i] = b[i] * c[i];
     	fft(a, -1); fft(b, -1);
     	for(int i = 1; i <= n; i++) {
     		printf("%.4f
    ", a[i].x - b[n - i].x);
     	}
    	return 0;
    }```
  • 相关阅读:
    ural 1146. Maximum Sum(动态规划)
    ural 1119. Metro(动态规划)
    ural 1013. K-based Numbers. Version 3(动态规划)
    Floyd算法
    杭电21题 Palindrome
    杭电20题 Human Gene Functions
    杭电15题 The Cow Lexicon
    杭电三部曲一、基本算法;19题 Cow Bowling
    杭电1002 Etaoin Shrdlu
    Qt 学习之路 2(37):文本文件读写
  • 原文地址:https://www.cnblogs.com/Mr-WolframsMgcBox/p/9080982.html
Copyright © 2011-2022 走看看