P1471 方差

原题链接

  • 题解:手推一下就知道了是要维护一个平方和的序列,然后就大力码码码。
  • 代码:
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;
const ll inf = 0x3f3f3f3f;
const ll N = 1e5 + 9;
typedef  long double lb;
const lb eps = 1e-7;
lb a[N];
struct segment_tree{
    struct node {
        ll l, r, L, R;
        lb data1, data2, lazy;
    }tr[N << 2];
    void pushup(ll p) {
        tr[p].data1 = tr[tr[p].l].data1 + tr[tr[p].r].data1;
        tr[p].data2 = tr[tr[p].l].data2 + tr[tr[p].r].data2;
        return;
    }
    void pushdown(ll p) {
        lb b = tr[p].lazy;
        tr[p].lazy = 0.0;
        ll L = tr[p].l;
        ll R = tr[p].r;
        tr[L].data2 += tr[L].data1*2.0*b +b* b *  (tr[L].R - tr[L].L + 1.0);
        tr[R].data2 += tr[R].data1 * 2.0 * b + b * b * (tr[R].R - tr[R].L + 1.0);
        tr[L].data1 += (tr[L].R - tr[L].L + 1.0) * b;
        tr[R].data1 += (tr[R].R - tr[R].L + 1.0) * b;
        tr[L].lazy += b;
        tr[R].lazy += b;
        return;
    }
    void build(ll l, ll r, ll p) {
        tr[p].l = p << 1;
        tr[p].r = p << 1 | 1;
        tr[p].L = l, tr[p].R = r;
        if (l == r) {
            tr[p].data1 = a[l];
            tr[p].data2 = a[l] * a[l];
            return;
        } 
        lb mid = l + r >> 1;
        build(l, mid, tr[p].l);
        build(mid + 1, r, tr[p].r);
        pushup(p);
    }
    void add(ll l, ll r, lb num, ll p) {
        if (tr[p].L >= l && tr[p].R <= r) {
            tr[p].data2 += 2.0 * num * tr[p].data1 + num * num * (tr[p].R - tr[p].L + 1.0);
            tr[p].data1 += num * (lb)(tr[p].R - tr[p].L + 1.0);
            tr[p].lazy += num;
            return;
        }
        pushdown(p);
        if (tr[tr[p].l].R >= l)add(l, r, num, tr[p].l);
        if (tr[tr[p].r].L <= r)add(l, r, num, tr[p].r);
        pushup(p);
    }
    lb ask(ll l, ll r, ll p, ll op) {
        if (tr[p].L >= l && tr[p].R <= r) {
            if (op==1)
            return tr[p].data1;
            return tr[p].data2;
        }
        pushdown(p);
        lb ret = 0;
        if (tr[tr[p].l].R >= l)ret += ask(l, r, tr[p].l, op);
        if (tr[tr[p].r].L <= r)ret += ask(l, r, tr[p].r, op);
        return ret;
    }
}T;
signed main() {
    ll n, m;
    scanf("%lld%lld",  &n, &m);
    for (int i = 1; i <= n; i ++)scanf("%Lf", &a[i]);// cout << a[i] << " ";
    T.build(1, n, 1);
    while (m--) {
        ll op;
        scanf("%lld", &op);
        if (op == 1) {
            ll l, r;
            lb x;
            scanf("%lld%lld%Lf", &l, &r, &x);
            T.add(l, r, x, 1);
        }
        else if (op == 2) {
            ll l, r;
            scanf("%lld%lld", &l, &r);
            printf("%.4Lf\n", T.ask(l, r, 1, 1) * 1.0/(r-l + 1.0));
        }
        else {
            ll l, r;
            scanf("%lld%lld", &l, &r);
            lb sum = T.ask(l, r, 1, 2);
            lb av = T.ask(l, r, 1, 1) * 1.0/(r-l + 1.0);
            lb len = r-l + 1;
            lb x = sum - 2 *T.ask(l, r, 1, 1) * av + len * av * av;
            printf("%.4Lf\n", x / len);
        }
    }
}

posted @ 2021-04-23 11:19  u_yan  阅读(50)  评论(0编辑  收藏  举报