http://poj.org/problem?id=3468题目大意:给出一组数组v[i],有两种操作,一种给出两个数a,b。要求输出v[a]到v[b]之间的和。还有一种给出三个数a,b,c,让v[a]到v[b]之间的数全都加上c。全然是树状数组可以实现的功能,可是假设就这样单纯的套用模板,做另外一种操作是更新每一个值,这种操作就有可能超时。换一种思路,既"/>

POJ 3468 A Simple Problem with Integers 树状数组

Posted gcczhongduan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3468 A Simple Problem with Integers 树状数组相关的知识,希望对你有一定的参考价值。

题目链接:http://poj.org/problem?id=3468

题目大意:给出一组数组v[i],有两种操作,一种给出两个数a,b。要求输出v[a]到v[b]之间的和。还有一种给出三个数a,b,c,让v[a]到v[b]之间的数全都加上c。

全然是树状数组可以实现的功能,可是假设就这样单纯的套用模板,做另外一种操作是更新每一个值,这种操作就有可能超时。

换一种思路,既然另外一种操作是给某区间上的全部数加上同样的值,那么应该是可以简化的才对。

如果数组sum[i]为原数组从v[1]到v[i]的和。数组c1[i]为更新之后,v[i]到v[n]的添加量。分析一下结果ans:

a,b之间的和ans=sum[b]-sum[a-1]+c1[1]*x + c1[2]*(x-1) + c1[3]*(x-2)+...+c1[x]*1

ans=sum[b]-sum[a-1]+segema(c1[i]*(x-i+1))

ans=sum[b]-sum[a-1] + (x+1)*segma(c1[i]) - segma(c1[i]*i)

令c2[i]=c1[i]*i;

如此便能利用树状数组解出此题

代码:

#include <stdio.h>
#define N 100001
#define lowbit(i) ( i & (-i) )
int n;
__int64 v[N];
__int64 c1[N];// 每一个C数组代表v[i-lowbit(i)+1]到v[i]之间的和
__int64 c2[N];
__int64 sum[N];

void Updata(__int64 *array,__int64 i,__int64 a)
{
    for(;i<=n;i+=lowbit(i))
        array[i]+=a;
}
__int64 Sumv(__int64 *array,__int64 i)   //求出数组v[1]到v[i]的和
{
    __int64 result=0;
    while (i>=1)
    {
        result+=array[i];
        i-=lowbit(i);
    }
    return result;
}
int main()
{
    __int64 q,i=0;
    __int64 ans=0;
    scanf("%I64d%I64d",&n,&q);
    for(i=1;i<=n;i++)
        scanf("%I64d",&v[i]);
    for(__int64 i=1;i<=n;i++)
        sum[i]=sum[i-1]+v[i];
    while(q--)
    {
        char ch[2];
        scanf("%s",ch);
        if(ch[0]=='Q')
        {
            __int64 s,t;
            scanf("%I64d%I64d",&s,&t);
            ans=sum[t]-sum[s-1];
            ans+=((t+1)*Sumv(c1,t)-Sumv(c2,t));
            ans-=(s*Sumv(c1,s-1)-Sumv(c2,s-1));
            printf("%I64d\n",ans);
        }
        else
        {
            __int64 a,b,c;
            scanf("%I64d%I64d%I64d",&a,&b,&c);
            Updata(c1,a,c);
            Updata(c1,b+1,-c);
            Updata(c2,a,c*a);
            Updata(c2,b+1,-c*(b+1));
        }
    }
    return 0;
}


以上是关于POJ 3468 A Simple Problem with Integers 树状数组的主要内容,如果未能解决你的问题,请参考以下文章

A Simple Problem with Integers POJ - 3468

POJ - 3468 A Simple Problem with Integers

[poj3468]A Simple Problem with Integers

POJ3468 a simple problem with integers 分块

POJ 3468 A Simple Problem with Integers 树状数组

POJ 3468 A Simple Problem with Integers