• 牛客网NOIP赛前集训营-提高组(第二场)A 方差


    链接:https://www.nowcoder.com/acm/contest/173/A
    来源:牛客网

    题目描述

    一个长度为 m 的序列 b[1...m] ,我们定义它的方差为 ,其中  表示序列的平均值。
    可以证明的是,如果序列元素均为整数,那么方差乘以 m^2 之后,得到的值一定是整数。

    现在有一个长度为 N 的序列 a[1...N],对每个 i = 1~N,你需要计算,如果我们删除 a[i],剩下的 N-1 个元素的方差乘以 (N-1)^2 的值。

    输入描述:

    第一行一个整数 N。
    接下来一行 N 个整数,第 i 个数表示 a[i]。

    输出描述:

    一行 N 个整数,第 i 个数表示删掉 a[i] 后,剩下元素的方差乘以 (N-1)^2 的值。
    示例1

    输入

    复制
    4
    1 1 1 2

    输出

    复制
    2 2 2 0
    

    说明

    依定义可以计算 {1, 1, 2} 的方差为 1/3 * (1/9 + 1/9 + 4/9) = 2/9,{1, 1, 1} 的方差为 0

    备注:

    对全部的测试数据,N <= 10^5, | a[i] | <= 10^4

    * 30 分的数据,N <= 1000
    * 30 分的数据,N <= 10^5, a[i] 只有 30 种不同的取值
    * 40 分的数据,无特殊限制

    对于题目给出的石子我们当然要化简了,答案要乘$(n-1)^2$不如提前乘进去,那么式子:

    将n-1带入,n-1也就是公式中的m
    $$frac{1}{n-1} sum_{i=1}^{n-1}(b_i-overline{b})^2 imes (n-1)^2=(n-1) imes sum_{i=1}^{n-1}(b_i-overline{b})^2$$

    下面我们继续处理这个式子:
    首先我们都知道$(a-b)^2=a^2+b^2-2ab$
    那么

    $$
    egin{aligned}
    (n-1)sum_{i=1}^{n-1}(b_i-overline{b})^2&=(n-1) imessum_{i=1}^{n-1}({b_i}^2+overline{b}^2+2b_i overline{b})\
    &=(n-1) imes left( sum_{i=1}^{n-1}{b_i}^2+sum_{i=1}^{n-1} overline{b}^2+sum_{i=1}^{n-1}2b_i overline{b} ight)\
    &=(n-1) imes sum_{i=1}^{n-1}{b_i}^2+(n-1) imes sum_{i=1}^{n-1} overline{b}^2-(n-1) imessum_{i=1}^{n-1}2b_i overline{b}\
    ext{因为}overline{b}&=frac{sum_{i=1}^{n-1}b_i}{n-1}\
    &=(n-1) imessum_{i=1}^{n-1}{b_i}^2+(n-1) imesoverline{b}-(n-1) imes sum_{i=1}^{n-1}{2b_i}-(n-1) imes sum_{i=1}^{n-1}b_i\
    &=(n-1) imes sum_{i=1}^{n-1}{b_i}^2-(sum_{i=1}^{n-1})^2
    end{aligned}
    $$

    答案是每个数的平方和减去每个数和的平方
    那么我们只需要记录两个前缀和对于每个数$O(1)$输出,总时间复杂度$O(n)$

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    using namespace std;
    #define LL long long
    LL a[100005];
    LL sum1[100005],sum2[100005],n;
    // sum(bi^2-2bi*b+b^2)*(n-1)
    int main()
    {
        scanf("%lld",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum1[i]=sum1[i-1]+a[i]*a[i];
            sum2[i]=sum2[i-1]+a[i];
        }
        LL num1=(sum1[n]-sum1[1])*(n-1);
        LL num2=sum2[n]-sum2[1];
        printf("%lld",num1-num2*num2);
        for(int i=2;i<=n;i++)
        {
            LL num1=(sum1[n]-sum1[i]+sum1[i-1])*(n-1);
            LL num2=sum2[n]-sum2[i]+sum2[i-1];
            printf(" %lld",num1-num2*num2);
        }
    }
  • 相关阅读:
    poj 2485 Highways 最小生成树
    hdu 3415 Max Sum of MaxKsubsequence
    poj 3026 Borg Maze
    poj 2823 Sliding Window 单调队列
    poj 1258 AgriNet
    hdu 1045 Fire Net (二分图匹配)
    poj 1789 Truck History MST(最小生成树)
    fafu 1181 割点
    减肥瘦身健康秘方
    人生的问题
  • 原文地址:https://www.cnblogs.com/rmy020718/p/9656418.html
Copyright © 2020-2023  润新知