poj 3468A Simple Problem with Integers(樹狀數組區間修改)

題目鏈接:http://poj.org/problem?id=3468

思路:s[i]表示原來1到i的和 s1[i]表示區間修改後1到i的和    區間修改爲[l,r]區間上加a

i<l s1[i]=s[i]
l<=i<=r s1[i]=s[i]+a*i-a*(l-1)
r<i s1[i]=s[i]+a*(r-l+1)

sum[i]=c[i]*i+d[i]

則與上圖表格對應的修改爲

c在l處+a

c在r+1處-a

d在l處-a*(l-1)

d在r+1處+a*r

#include<cstdio>
#include<cstring>
using namespace std;
const int num=100005;
__int64 c[num],d[num];
int n,m;
int lowbit(int a)
{
    return a&(-a);
}
void add(__int64 *a,int p,int ad)
{
    while(p<=n)
    {
        a[p]+=ad;
        p+=lowbit(p);
    }
}
__int64 sum(__int64 *a,int p)
{
    __int64 s=0;
    while(p>0)
    {
        s+=a[p];
        p-=lowbit(p);
    }
    return s;
}
int main()
{
    int i,a,b,q;
    __int64 ans;
    char s[3];
    //freopen("in.txt","r",stdin);
    scanf("%d%d",&n,&m);
    memset(c,0,sizeof(c));
    memset(d,0,sizeof(d));
    for(i=1;i<=n;i++)
    {
        scanf("%d",&a);
        add(d,i,a);
    }
    while(m--)
    {
        scanf("%s",s);
        if(s[0]=='Q')
        {
            scanf("%d%d",&a,&b);
            ans=(b*sum(c,b)+sum(d,b))-((a-1)*sum(c,a-1)+sum(d,a-1));  //注意此處求[a,b]爲sum[b]-sum[a-1]
            printf("%I64d\n",ans);
        }
        else
        {
            scanf("%d%d%d",&a,&b,&q);
            add(c,a,q);
            add(c,b+1,-q);
            add(d,a,-q*(a-1));
            add(d,b+1,q*b);
        }
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章