1. 程式人生 > >詳解樹狀陣列 區間修改求和

詳解樹狀陣列 區間修改求和

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 102333
using namespace std;
typedef long long ll;
int n,m;
ll a[N],c1[N],c2[N];
inline int lowbit(int x){return x&(-x);}
void add(ll *r,int pos, ll v)
{
    for(;pos<=n;pos+=lowbit(pos))r[pos]+=v;
}
ll getsum(ll *r,int pos)
{
    ll re=0;
    for(;pos>0;pos-=lowbit(pos))re+=r[pos];
    return re;
}
ll sigma(int r)
{
    ll sum1=r*getsum(c1,r),sum2=getsum(c2,r);
    return sum1-sum2;
}
ll query(int x,int y)
{
    return sigma(y)-sigma(x-1);
}
int flag,x,y;ll k;
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        add(c1,i,a[i]-a[i-1]);
        add(c2,i,(i-1)*(a[i]-a[i-1]));
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d",&flag);
        if(flag==1)
        {
            scanf("%d%d%lld",&x,&y,&k);
            add(c1,x,k);add(c1,y+1,-k);
            add(c2,x,(x-1)*k);add(c2,y+1,y*(-k));
        }
        else
        {
            scanf("%d%d",&x,&y);
            printf("%lld\n",query(x,y));
        }
    }
    return 0;
}