H — Variance
Time Limit:1s Memory Limit:128MByte
Submissions:259Solved:80
DESCRIPTION
An array with length n is given.
You should support 2 types of operations.
1 x y change the x-th element to y.
2 l r print the variance of the elements with indices l, l + 1, … , r.
As the result may not be an integer, you need print the result after multiplying (r-l+1)^2.
The index of the array is from 1.
INPUT The first line is two integer n, m(1 <= n, m <= 2^{16}), indicating the length of the array and the number of operations.The second line is n integers, indicating the array. The elements of the array
0<=ai<=1040<=ai<=104.The following m lines are the operations. It must be either1 x yor2 l r OUTPUT For each query, print the result. SAMPLE INPUT 4 41 2 3 42 1 41 2 42 1 42 2 4 SAMPLE OUTPUT 20242
题意:给定n个值,每次可以改变其中某个值,也可以询问其中一个区间的方差。输出每次询问的结果。
思路:线段树。需要用到方差公式Dx=E(X^2)-(E(X))^2。结点储存该区间内平方和及和。
#include <iostream>
#include <algorithm>
#include <string.h>
#include <stdio.h>
#include <math.h>
using namespace std;
#define maxn 65540
struct node{
int l,r;
long long sum2,sum;
}n[4*maxn];
long long a[maxn];
long long sum2;
long long sum;
void build(int l,int r,int i){
n[i].l=l;
n[i].r=r;
if(n[i].l==n[i].r){
n[i].sum=a[l];
n[i].sum2=a[l]*a[l];
return;
}
int mid=(l+r)/2;
build(l,mid,i*2);
build(mid+1,r,i*2+1);
n[i].sum=n[2*i].sum+n[2*i+1].sum;
n[i].sum2=n[2*i].sum2+n[2*i+1].sum2;
}
void update(int num,int s,int i){
if(n[i].l==num&&n[i].r==num){
n[i].sum=s;
n[i].sum2=s*s;
return;
}
int mid=(n[i].l+n[i].r)/2;
if(num<=mid)
update(num,s,2*i);
else
update(num,s,2*i+1);
n[i].sum=n[2*i].sum+n[2*i+1].sum;
n[i].sum2=n[2*i].sum2+n[2*i+1].sum2;
}
void query(int l,int r,int i){
if(n[i].l==l&&n[i].r==r){
sum2+=n[i].sum2;
sum+=n[i].sum;
return;
}
int mid=(n[i].l+n[i].r)/2;
if(r<=mid)
query(l,r,2*i);
else if(l>mid)
query(l,r,2*i+1);
else{
query(l,mid,2*i);
query(mid+1,r,2*i+1);
}
}
int main(){
int n,m;
while(~scanf("%d %d",&n,&m)){
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
}
build(1,n,1);
while(m--){
int q;
scanf("%d",&q);
if(q==1){
int num,y;
scanf("%d %d",&num,&y);
update(num,y,1);
}
else{
int l,r;
sum2=0;
sum=0;
scanf("%d %d",&l,&r);
query(l,r,1);
long long ans=(r-l+1)*sum2-sum*sum;
printf("%lld\n",ans);
}
}
}
return 0;
}