社区讨论

今天是大喜的日子,所以应该调个红色的代码

P1471方差参与者 2已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lo7ioyhv
此快照首次捕获于
2023/10/27 02:28
2 年前
此快照最后确认于
2023/10/27 02:28
2 年前
查看原帖
CPP
#include <bits/stdc++.h>
#define square(x) ((x)*(x))
#define int long double
using namespace std;
signed arr[100005];
struct SegmentTree{
    struct Tree{
        signed left, right;
        int sum, squ, add;
    }tree[400010];
    void build(signed p, signed l, signed r){
        tree[p].left = l, tree[p].right = r;
        if(l == r){
            tree[p].sum = arr[l];
            tree[p].squ = square(arr[l]);
            return;
        }
        signed mid = (l + r) / 2;
        build(p * 2, l, mid);
        build(p * 2 + 1, mid + 1, r);
        tree[p].sum = tree[p * 2].sum + tree[p * 2 + 1].sum;
        tree[p].squ = tree[p * 2].squ + tree[p * 2 + 1].squ;
        return;
    }
    void pushdown(signed p){
        if(tree[p].add){
            tree[p * 2].add += tree[p].add, tree[p * 2 + 1].add += tree[p].add;
            tree[p * 2].squ += 2 * ((tree[p * 2].right - tree[p * 2].left + 1) * tree[p].add + tree[p * 2].sum * tree[p].add);
            tree[p * 2 + 1].squ += 2 * ((tree[p * 2 + 1].right - tree[p * 2 + 1].left + 1) * tree[p].add + tree[p * 2 + 1].sum * tree[p].add);
            tree[p * 2].sum += (tree[p * 2].right - tree[p * 2].left + 1) * tree[p].add;
            tree[p * 2 + 1].sum += (tree[p * 2 + 1].right - tree[p * 2 + 1].left + 1) * tree[p].add;
            tree[p].add = 0;
        }
    }
    void modify(signed p, signed l, signed r, signed val){
        if(l <= tree[p].left && r >= tree[p].right){
            tree[p].squ += 2 * ((tree[p].right - tree[p].left + 1) * val + tree[p].sum * val);
            tree[p].sum += val * (tree[p].right - tree[p].left + 1);
            tree[p].add += val;
            return;
        }
        pushdown(p);
        signed mid = (tree[p].left + tree[p].right) / 2;
        if(l <= mid) modify(p * 2, l, r, val);
        if(r > mid) modify(p * 2 + 1, l, r, val);
        tree[p].sum = tree[p * 2].sum + tree[p * 2 + 1].sum;
        tree[p].squ = tree[p * 2].squ + tree[p * 2 + 1].squ;
        return;
    }
    pair<int, int> query(signed p, signed l, signed r){
        if(l <= tree[p].left && r >= tree[p].right){
            return make_pair(tree[p].sum, tree[p].squ);
        }
        pushdown(p);
        pair<int, int> ret = {0.0, 0.0};
        signed mid = (tree[p].left + tree[p].right) / 2;
        if(l <= mid){
            auto res = query(p * 2, l, r);
            ret.first += res.first, ret.second += res.second;
        }
        if(r > mid){
            auto res = query(p * 2 + 1, l, r);
            ret.first += res.first, ret.second += res.second;
        }
        return ret;
    }
}STree;
signed main(){
    signed n, m;
    scanf("%d %d", &n, &m);
    for(signed i = 1; i <= n; i++) scanf("%d", &arr[i]);
    STree.build(1, 1, n);
    while(m--){
        signed op, x, y;
        scanf("%d %d %d", &op, &x, &y);
        if(op == 1){
            int k;
            scanf("%Le", &k);
            STree.modify(1, x, y, k);
        }else if(op == 2){
            auto result = STree.query(1, x, y);
            printf("%.4Lf\n", result.first / (int)(y - x + 1));
        }else if(op == 3){
            auto result = STree.query(1, x, y);
            int avg = result.first / (int)(y - x + 1);
            printf("%.4Lf\n", (result.second + (y - x + 1) * avg * avg - 2 * avg * result.first) / (y - x + 1));
        }
    }
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...