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

    (color{#0066ff}{ 题目描述 })

    给出n个数qi,给出Fj的定义如下:

    (F_j = sum_{i<j}frac{q_i q_j}{(i-j)^2 }-sum_{i>j}frac{q_i q_j}{(i-j)^2 })

    令Ei=Fi/qi,求Ei.

    (color{#0066ff}{输入格式})

    第一行一个整数n。

    接下来n行每行输入一个数,第i行表示qi。

    接下来为边

    (color{#0066ff}{输出格式})

    n行,第i行输出Ei。

    与标准答案误差不超过1e-2即可。

    (color{#0066ff}{输入样例})

    5
    4006373.885184
    15375036.435759
    1717456.469144
    8514941.004912
    1410681.345880
    

    (color{#0066ff}{输出样例})

    -16838672.693
    3439.793
    7509018.566
    4595686.886
    10903040.872
    

    (color{#0066ff}{数据范围与提示})

    对于30%的数据,n≤1000。

    对于50%的数据,n≤60000。

    对于100%的数据,n≤100000,0<qi<1000000000。

    (color{#0066ff}{ 题解 })

    (q_i)除掉

    (f_i=p_i, g_i=frac{1}{i^2})

    (egin{aligned}F_i=sum_{j = 1}^{i - 1}f(j)*g(i-j)-sum_{j = i +1}^{n}f(j)*g(j-i)end{aligned})

    考虑一个卷积(egin{aligned}f_n=sum_{i = 1}^n g(i)*h(n - i) end{aligned})

    一个函数(f(i)),当做多项式,就是(x^i)的系数

    不难发现,因为(i + n - i) = n

    所以上面的卷积其实就是g和h卷起来第n项的系数!

    回到本题

    将前面的(sum)用FFT算出来,因为(j+i-j=i),因此前面的部分第i项的系数就是第i个ans

    后面的(sum)不好弄,要把j消掉,可以将后面翻转成(egin{aligned}sum_{j = i + 1}^{n}f(j)*g(n - (j - i)+1)end{aligned})

    (j + n -j+i+1=n+i+1),所以后半部分的第i个ans就是卷积的第n+i+1项(把g翻转后再卷积)

    #include<bits/stdc++.h>
    #define LL long long
    LL in() {
    	char ch; LL x = 0, f = 1;
    	while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);
    	for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));
    	return x * f;
    }
    const double pi = acos(-1);
    const int maxn = 3e5 + 10;
    double p[maxn];
    struct node {
    	double x, y;
    	node(double x = 0, double y = 0): x(x), y(y) {}
    	friend node operator + (const node &a, const node &b) { return node(a.x + b.x, a.y + b.y); }
    	friend node operator - (const node &a, const node &b) { return node(a.x - b.x, a.y - b.y); }
    	friend node operator * (const node &a, const node &b) { return node(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x); }
    	friend node operator / (const node &a, const double &b) { return node(a.x / b, a.y / b); }
    }A[maxn], B[maxn], E[maxn], F[maxn];
    int len, n, r[maxn];
    void FFT(node *D, int flag) {
    	for(int i = 0; i < len; i++) if(i < r[i]) std::swap(D[i], D[r[i]]);
    	for(int l = 1; l < len; l <<= 1) {
    		node w0(cos(pi / l), flag * sin(pi / l));
    		for(int i = 0; i < len; i += (l << 1)) {
    			node w(1, 0), *a0 = D + i, *a1 = D + i + l;
    			for(int k = 0; k < l; k++, a0++, a1++, w = w * w0) {
    				node tmp = *a1 * w;
    				*a1 = *a0 - tmp;
    				*a0 = *a0 + tmp;
    			}
    		}
    	}
    	if(flag == -1) for(int i = 0; i < len; i++) D[i] = D[i] / len;
    }
    int main() {
    	n = in();
    	for(int i = 1; i <= n; i++) scanf("%lf", &p[i]);
    	for(int i = 1; i <= n; i++) A[i].x = p[i];
    	for(int i = 1; i <= n; i++) B[i].x = 1.0 / i / i;
    	for(len = 1; len <= n + n + 2; len <<= 1);
    	for(int i = 0; i < len; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) * (len >> 1));
    	FFT(A, 1), FFT(B, 1);
    	for(int i = 0; i < len; i++) E[i] = A[i] * B[i];
    	FFT(E, -1);
    	for(int i = 0; i < len; i++) A[i] = B[i] = node();
    	for(int i = 1; i <= n; i++) A[i].x = p[i];
    	for(int i = 1; i <= n; i++) B[i].x = 1.0 / (n - i + 1) / (n - i + 1); 
    	FFT(A, 1), FFT(B, 1);
    	for(int i = 0; i < len; i++) F[i] = A[i] * B[i];
    	FFT(F, -1);
    	for(int i = 1; i <= n; i++) printf("%.3f
    ", E[i].x - F[n + i + 1].x);
    	return 0;
    }
    
  • 相关阅读:
    pip换国内源
    docker build 的 cache 机制
    jenkins 修改log路径
    lsb_release: command not found 解决
    Linux 添加开机启动项的三种方法
    FAT AP v200R005 配置二层透明模式(web&命令行,开局)
    SharePoint 2010 文档管理系列之星级评论功能
    SharePoint 2010 文档管理之过期归档工具
    SharePoint 2010 文档管理系列之文档搜索
    SharePoint 2010 文档管理系列之准备篇
  • 原文地址:https://www.cnblogs.com/olinr/p/10270095.html
Copyright © 2011-2022 走看看