“玲瓏杯” 線上賽 Round #5 Variance(線段樹)

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;  
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章