1063 - Variance
Time Limit:1s Memory Limit:128MByte
Submissions:332Solved:101
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 4
1 2 3 4
2 1 4
1 2 4
2 1 4
2 2 4
SAMPLE OUTPUT
20
24
2
题意:给定n个值,每次可以改变其中某个值,也可以询问其中一个区间的方差。输出每次询问的结果。
思路:线段树。需要用到方差公式Dx=E(X^2)-(E(X))^2。结点储存该区间内平方和及和。
#include<stdio.h>
#include<iostream>
using namespace std;
long long int a[70000],b[70000],c[70000];
int n;
long long int lowbit(long long int i)
{
return i&-i;
}
void add(long long int i,long long int num)
{
while(i<=n)
{
b[i]+=num;
i+=lowbit(i);
}
}
void add1(long long int i,long long int num)
{
while(i<=n)
{
c[i]+=num;
i+=lowbit(i);
}
}
long long int sum1(long long int i)
{
long long int sum=0;
while(i>0)
{
sum+=b[i];
i-=lowbit(i);
}
return sum;
}
long long int sum2(long long int i)
{
long long int sum=0;
while(i>0)
{
sum+=c[i];
i-=lowbit(i);
}
return sum;
}
int main()
{
long long int m;
while(scanf("%d%lld",&n,&m)!=-1)
{
for(long long int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
add(i,a[i]);
add1(i,a[i]*a[i]);
}
long long int ans;
while(m--)
{
long long int w,e,r;
scanf("%lld%lld%lld",&w,&e,&r);
if(w==1)
{
long long int ha;
ha=r-a[e];
add(e,ha);
long long int haha=r*r-a[e]*a[e];
add1(e,haha);
a[e]=r;
}
else {
if(e>1)
ans=-(sum1(r)-sum1(e-1))*(sum1(r)-sum1(e-1))+(r-e+1)*(sum2(r)-sum2(e-1));
else ans=-sum1(r)*sum1(r)+r*(sum2(r));
printf("%lld\n",ans);
}
}
}
}