Variance

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);
            }
            }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值