您的位置:首页 > 其它

“玲珑杯” 线上赛 Round #5 Variance(线段树)

2017-09-10 17:56 246 查看
1063 -- Variance

线段树:1.单点更新   2.区间方差 *(r-l+1)^2

ps:方差:Var[x]=E[x^2]-E[x]^2

代码:

#include <bits/stdc++.h>
using namespace std;

#define LL long long
const int maxn=2<<18;

LL a[maxn];
LL sum[maxn];

void pushup(int rt){
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
a[rt]=a[rt<<1]+a[rt<<1|1];
}

void build(int l,int r,int rt){
if(l==r){
scanf("%d",&sum[rt]);
a[rt]=sum[rt]*sum[rt];
return ;
}
int m=(l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
pushup(rt);
}

void update(int p,int add,int l,int r,int rt){
if(l==r){
sum[rt]=add;
a[rt]=add*add;
return ;
}
int m=(l+r)>>1;
if(p<=m) update(p,add,l,m,rt<<1);
else update(p,add,m+1,r,rt<<1|1);
pushup(rt);
}

LL query1(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return sum[rt];
}
int m = (l + r) >> 1;
LL ret = 0;
if (L <= m) ret += query1(L,R,l,m,rt<<1);
if (R > m) ret+= query1(L,R,m+1,r,rt<<1|1);
return ret;
}

LL query2(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return a[rt];
}
int m = (l + r) >> 1;
LL ret = 0;
if (L <= m) ret += query2(L,R,l,m,rt<<1);
if (R > m) ret+= query2(L,R,m+1,r,rt<<1|1);
return ret;
}

int main(){
int n,m,q,l,r;
scanf("%d%d",&n,&m);
build(1,n,1);
while(m--){
scanf("%d%d%d",&q,&l,&r);
if(q==1){
update(l,r,1,n,1);
}else{
LL s=query1(l,r,1,n,1);
LL d=query2(l,r,1,n,1);
int e=r-l+1;
LL ans=d*e-s*s;
printf("%lld\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: