社区讨论
线段树求调
P1471方差参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @m4gk6lqg
- 此快照首次捕获于
- 2024/12/09 12:54 去年
- 此快照最后确认于
- 2025/11/04 13:05 4 个月前
CPP
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#define int long long
using namespace std;
struct node{
int sum1,sum2,l,r;
int lazy;
}tr[800005];
int n,m,a[100005];
void pushdown(int p){
tr[p * 2].sum1 += (tr[p * 2].r - tr[p * 2].l + 1) * tr[p].lazy;
tr[p * 2 + 1].sum1 += (tr[p * 2 + 1].r - tr[p * 2 + 1].l + 1) * tr[p].lazy;
tr[p * 2].sum2 += (tr[p * 2].r - tr[p * 2].l + 1) * tr[p].lazy * tr[p].lazy + 2 * tr[p].lazy * tr[p * 2].sum1;
tr[p * 2 + 1].sum2 += (tr[p * 2 + 1].r - tr[p * 2 + 1].l + 1) * tr[p].lazy * tr[p].lazy + 2 * tr[p].lazy * tr[p * 2 + 1].sum1;
tr[p * 2].lazy = tr[p].lazy;
tr[p * 2 + 1].lazy = tr[p].lazy;
return ;
}
void build(int p,int l,int r){
tr[p].l = l,tr[p].r = r;
if(l == r){
tr[p].sum1 = a[l];
tr[p].sum2 = a[l] * a[l];
return ;
}
int mid = (tr[p].l + tr[p].r) / 2;
build(p * 2,l,mid);
build(p * 2 + 1,mid + 1,r);
tr[p].sum1 = tr[p * 2].sum1 + tr[p * 2 + 1].sum1;
tr[p].sum2 = tr[p * 2].sum2 + tr[p * 2 + 1].sum2;
return ;
}
void add(int p,int l,int r,int k){
if(l <= tr[p].l && tr[p].r <= r){
tr[p].lazy += k;
tr[p].sum1 += (tr[p].r - tr[p].l + 1) * k;
tr[p].sum2 += (tr[p].r - tr[p].l + 1) * k * k + 2 * k * tr[p].sum1;
return ;
}
pushdown(p);
int mid = (tr[p].l + tr[p].r) / 2;
if(l <= mid) add(p * 2,l,r,k);
if(r > mid) add(p * 2 + 1,l,r,k);
tr[p].sum1 = tr[p * 2].sum1 + tr[p * 2 + 1].sum1;
tr[p].sum2 = tr[p * 2].sum2 + tr[p * 2 + 1].sum2;
return ;
}
int found(int p,int l,int r){
if(l <= tr[p].l && tr[p].r <= r) return tr[p].sum1;
pushdown(p);
int mid = (tr[p].l + tr[p].r) / 2,ans = 0;
if(l <= mid) found(p * 2,l,r);
if(r > mid) found(p * 2 + 1,l,r);
tr[p].sum1 = tr[p * 2].sum1 + tr[p * 2 + 1].sum1;
tr[p].sum2 = tr[p * 2].sum2 + tr[p * 2 + 1].sum2;
return ans;
}
int found_(int p,int l,int r){
if(l <= tr[p].l && tr[p].r <= r) return tr[p].sum2;
pushdown(p);
int mid = (tr[p].l + tr[p].r) / 2,ans = 0;
if(l <= mid) ans += found(p * 2,l,r);
if(r > mid) ans += found(p * 2 + 1,l,r);
tr[p].sum1 = tr[p * 2].sum1 + tr[p * 2 + 1].sum1;
tr[p].sum2 = tr[p * 2].sum2 + tr[p * 2 + 1].sum2;
return ans;
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i = 1;i <= n;i++) scanf("%lld",&a[i]);
build(1,1,n);
int op,x,y,k;
for(int i = 1;i <= m;i++){
scanf("%lld%lld%lld",&op,&x,&y);
if(op == 1){
scanf("%lld",&k);
add(1,x,y,k);
}
else if(op == 2){
double f = found(1,x,y) * 1.0 / (y - x + 1);
printf("%.4f\n",f);
}
else if(op == 3){
double f = found_(1,x,y) + (y - x + 1) * (found(1,x,y) * 1.0 / (y - x + 1)) * (found(1,x,y) * 1.0 / (y - x + 1)) - 2.0 * (found(1,x,y) * 1.0 / (y - x + 1)) * found(1,x,y);
printf("%.4f\n",f);
}
}
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...