POJ3468 - A Simple Problem with Integers

题目大意

给定N个整数,A1,A2,A3…An。可以对这些数进行一下两种操作:

1、"C a b c" 对区间[a,b]内的所有数都加上c

2、"Q a b"询问区间[a,b]的和

题解

一般树状数组都是实现单点修改和区间求和或者单点查询和区间加减的功能,而此题是要求实现区间查询,区间加减的功能,我们依然能够用树状数组来处理,具体怎么处理请参看wyl神牛的树状数组总结吧

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN  100005
long long a[MAXN],c[MAXN],b[MAXN];
int n,m;
using namespace std;
int lowbit(int x)
{
    return x&-x;
}
void add(long long  a[],int x,int d)
{
    while(x<=n)
    {
        a[x]+=d;
        x+=lowbit(x);
    }
}
long long   sum(long long  a[],int x)
{
    long long ret=0;
    while(x>0)
    {
        ret+=a[x];
        x-=lowbit(x);
    }
    return ret;
}
int main(void)
{
    int i,l,r,d;
    long long ans;
    char ch;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(c,0,sizeof(c));
        memset(b,0,sizeof(b));
        a[0]=0;
        for(i=1; i<=n; i++)
        {
            scanf("%lld",&a[i]);
            a[i]+=a[i-1];
        }
        for(i=1; i<=m; i++)
        {
            getchar();
            scanf("%c",&ch);
            if(ch=='C')
            {
                scanf("%d%d%d",&l,&r,&d);
                add(b,l,d);
                add(b,r+1,-d);
                add(c,l,d*l);
                add(c,r+1,-(r+1)*d);
            }
            else
            {
                scanf("%d%d",&l,&r);
                ans=a[r]-a[l-1]+(r+1)*sum(b,r)-l*(sum(b,l-1))-sum(c,r)+sum(c,l-1);
                printf("%lld\n",ans);
            }
        }
    }
    return 0;
}

 

 

posted on 2013-04-22 23:27  仗剑奔走天涯  阅读(169)  评论(0编辑  收藏  举报

导航