【樹狀陣列 區間更新區間查詢】code

CN_swords發表於2017-09-06
Link:http://codevs.cn/problem/1082/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;

//c[i] = a[i]-a[i-1]
//c2[i] = (i-1)*c[i]
//樹狀陣列維護c,c2
//ans[1-n]: n*sigma(c,n) - sigma(c2,n)
const int N = 200010;
#define lowbit(i) (i&(-i))
LL c[N],c2[N];
LL n;
void up(LL *r,LL x,LL val){
    while(x<=n){
        r[x] += val;
        x += lowbit(x);
    }
}
LL down(LL *r,LL x){
    LL ans = 0;
    while(x){
        ans += r[x];
        x -= lowbit(x);
    }
    return ans;
}

int main()
{
    LL q;
    scanf("%lld",&n);
    for(int i = 1; i <= n; i++){
        LL f;
        scanf("%lld",&f);
        up(c,i,f); up(c,i+1,-f);
        up(c2,i,f*(i-1)); up(c2,i+1,-f*(i));
    }
    scanf("%lld",&q);
    while(q--){
        int type;
        scanf("%d",&type);
        LL a,b,f;
        if(type==1){
            scanf("%lld%lld%lld",&a,&b,&f);
            up(c,a,f); up(c,b+1,-f);
            up(c2,a,f*(a-1)); up(c2,b+1,-f*b);
        }
        else{
            scanf("%lld%lld",&a,&b);
            LL l = (a-1)*down(c,a-1) - down(c2,a-1);
            LL r = b*down(c,b) - down(c2,b);
            printf("%lld\n",r-l);
        }
    }
    return 0;
}


相關文章