[Luogu] 方差

Posted shandongs1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[Luogu] 方差相关的知识,希望对你有一定的参考价值。

https://www.luogu.org/problemnew/show/P1471

线段树维护区间数的平方之和与和

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;

#define DB double
#define gc getchar()
#define lson jd << 1
#define rson jd << 1 | 1 

int n, m;
DB Answer, x_, imp_, W[N << 2], F[N << 2], A_2[N << 2], size[N << 2];

struct Read {
    inline int read_int() {
        int x = 0; char c = gc;
        while(c < 0 || c > 9) c = gc;
        while(c >= 0 && c <= 9) x = x * 10 + c - 0, c = gc;
        return x;
    }
    inline DB read_DB() {DB x; scanf("%lf", &x); return x;}
}ac;

void Build_tree(int l, int r, int jd) {
    size[jd] = (r - l + 1);
    if(l == r) {
        W[jd] = ac.read_DB();
        A_2[jd] = W[jd] * W[jd]; 
        return ;
    }
    int mid = (l + r) >> 1;
    Build_tree(l, mid, lson);
    Build_tree(mid + 1, r, rson);
    W[jd] = W[lson] + W[rson];
    A_2[jd] = A_2[lson] + A_2[rson];
}
                      
void Down(int jd) {
    DB yj = F[jd];
    F[lson] += yj; F[rson] += yj;
    A_2[lson] += (2 * yj * W[lson] + size[lson] * yj * yj);
    A_2[rson] += (2 * yj * W[rson] + size[rson] * yj * yj);
    W[lson] += size[lson] * yj;
    W[rson] += size[rson] * yj;
    F[jd] = 0;
}

void Sec_G(int l, int r, int jd, int x, int y, DB yj) {
    if(x <= l && r <= y) {
        F[jd] += yj;
        A_2[jd] += (2 * yj * W[jd] + size[jd] * yj * yj);
        W[jd] += size[jd] * yj;
        return ;
    }
    if(F[jd]) Down(jd);
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_G(l, mid, lson, x, y, yj);
    if(y > mid)  Sec_G(mid + 1, r, rson, x, y, yj);
    W[jd] = W[lson] + W[rson];
    A_2[jd] = A_2[lson] + A_2[rson]; 
} 

void Sec_A_w(int l, int r, int jd, int x, int y) {
    if(x <= l && r <= y) {
        Answer += W[jd];
        return ;
    } 
    if(F[jd]) Down(jd);
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_A_w(l, mid, lson, x, y);
    if(y > mid)  Sec_A_w(mid + 1, r, rson, x, y); 
}

void Sec_A_A(int l, int r, int jd, int x, int y) {
    if(x <= l && r <= y) {
        imp_ += A_2[jd];
        return ;
    } 
    if(F[jd]) Down(jd);
    int mid = (l + r) >> 1;
    if(x <= mid) Sec_A_A(l, mid, lson, x, y);
    if(y > mid)  Sec_A_A(mid + 1, r, rson, x, y); 
}

int main() {
    n = ac.read_int();
    m = ac.read_int();
    Build_tree(1, n, 1);
    while(m --) {
        int opt = ac.read_int();
        if(opt == 1) {
            int x = ac.read_int(), y = ac.read_int(), k = ac.read_DB();
            Sec_G(1, n, 1, x, y, k);
        } else if(opt == 2) {
            Answer = 0;
            int x = ac.read_int(), y = ac.read_int();
            Sec_A_w(1, n, 1, x, y);
            printf("%.4lf\n", Answer / (y - x + 1));
        } else {
            Answer = 0;
            int x = ac.read_int(), y = ac.read_int();
            Sec_A_w(1, n, 1, x, y);
            x_ = Answer / (y - x + 1);
            imp_ = 0;
            Sec_A_A(1, n, 1, x, y);
            DB answer = imp_ - 2 * x_ * Answer + (y - x + 1) * x_ * x_;
            printf("%.4lf\n", answer / (y - x + 1));
        }
    }
    return 0;
}

                                                                     

以上是关于[Luogu] 方差的主要内容,如果未能解决你的问题,请参考以下文章

Luogu P1471 方差

P1471 方差

[luogu4072][bzoj4518][SDOI2016]征途

洛谷P1471 方差

均值方差和标准差计算的python代码

C语言 求方差