社区讨论
今天是大喜的日子,所以应该调个红色的代码
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 条回复,欢迎继续交流。
正在加载回复...