HDOJ线段树专题(A Simple Problem with Integers)

维护一个整数序列,支持2种操作:

1、修改:将给定区间中的每个数增加一个值;

2、查询:查询给定区间中所有数的和。

View Code
#include <stdio.h>

#define N 100010

#define Node 800000

int n,m,x[N];

long long sum[N];

int left[Node],right[Node];

long long incsum[Node],inc[Node];

void create(int i,int l,int r)

{

    left[i]=l;

    right[i]=r;

    inc[i]=0;

    incsum[i]=0;

    if(l==r)    return;

    int mid=(l+r)>>1;

    create(2*i,l,mid);

    create(2*i+1,mid+1,r);

}

void update(int i,int l,int r,int x)

{

    int mid=(left[i]+right[i])>>1;

    incsum[i]+=x*(r-l+1);

    if(left[i]==l && right[i]==r)

    {

        inc[i]+=x;

        return;

    }

    if(mid<l)

    {

        update(2*i+1,l,r,x);

    }

    else if(mid>=r)

    {

        update(2*i,l,r,x);

    }

    else

    {

        update(2*i,l,mid,x);

        update(2*i+1,mid+1,r,x);

    }

}

long long get(int i,int l,int r)

{

    int mid=(left[i]+right[i])>>1;

    if(inc[i])

    {

        inc[2*i]+=inc[i];

        inc[2*i+1]+=inc[i];

        incsum[2*i]+=inc[i]*(mid-left[i]+1);

        incsum[2*i+1]+=inc[i]*(right[i]-mid);

        inc[i]=0;

    }

    if(l==left[i] && r==right[i])   return incsum[i];

    if(mid<l)   return get(2*i+1,l,r);

    if(mid>=r)  return get(2*i,l,r);

    return get(2*i,l,mid)+get(2*i+1,mid+1,r);

}

int main()

{

    int i,a,b,c;

    char ch;

    while(~scanf("%d%d",&n,&m))

    {

        create(1,1,n);

        sum[0]=0;

        for(i=1;i<=n;i++)   scanf("%d",&x[i]),sum[i]=sum[i-1]+x[i];

        for(i=1;i<=m;i++)

        {

            ch=0;

            while(ch!='Q' && ch!='C')   scanf("%c",&ch);

            if(ch=='Q')

            {

                scanf("%d%d",&a,&b);

                printf("%lld\n",sum[b]-sum[a-1]+get(1,a,b));

            }

            else

            {

                scanf("%d%d%d",&a,&b,&c);

                update(1,a,b,c);

            }

        }

    }

    return 0;

}

你可能感兴趣的:(Integer)