17年sdnu选拔赛第2场----树状数组+方差公式

来源:互联网 发布:yy老虎机软件 编辑:程序博客网 时间:2024/04/28 18:59


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 <=10^4. The following m lines are the operations. It must be either 1 x y or 2 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

主要考察方差的使用,方差

维护x和x^2树状数组即可

#include<iostream>#include <cstdio>#include <cstring>#define ll long longusing namespace std;ll c[65550];ll c2[65550];ll a[65550];int lowbit(int x){    return x&(-x);}void add(int x,int val){    while(x<=65550)    {        c[x]+=val;        x+=lowbit(x);    }}void add2(int x,ll val){    while(x<=65550)    {        c2[x]+=val;        x+=lowbit(x);    }}ll sum(int x){    ll ans=0;    while(x>0)    {        ans+=c[x];        x-=lowbit(x);    }    return ans;}ll sum2(int x){    ll ans=0;    while(x>0)    {        ans+=c2[x];        x-=lowbit(x);    }    return ans;}int main(){    int n,m;    cin>>n>>m;    memset(c,0,sizeof(c));    memset(c2,0,sizeof(c2));    for(int i=1;i<=n;i++)    {        scanf("%lld",&a[i]);        add(i,a[i]);        add2(i,a[i]*a[i]);    }    while(m--)    {        int x;        scanf("%d",&x);        if(x==1)        {            int u;            ll v;            scanf("%d%lld",&u,&v);            add(u,v-a[u]);            add2(u,v*v-a[u]*a[u]);            a[u]=v;        }        else        {            int l,r;            scanf("%d%d",&l,&r);            ll E2=(sum2(r)-sum2(l-1))*(r-l+1);            ll E=sum(r)-sum(l-1);            ll D=E2-E*E;            printf("%lld\n",D);//在这里用cout在玲珑杯上超时,找了好久的原因        }    }    return 0;}


0 0
原创粉丝点击