1. 程式人生 > >【洛谷】線段樹 樹狀陣列區間修改區間查詢

【洛谷】線段樹 樹狀陣列區間修改區間查詢

在做一道整體二分的題目的時候遇到了這種區間修改區間查詢的樹狀陣列,感覺用起來手感不錯就拿來了。證明的話,那其實不重要,會用就好了

#include<cstdio>
#include<cstring>
#include<iostream>
#define maxn 500000
#define LL unsigned long long
using namespace std;
int n,m;
LL a[maxn],sum[maxn],c1[maxn],c2[maxn];
void update(int x,LL y){
	for(int i=x;i<=n;i+=i&(-i))
		c1[i]+=y,c2[i]+=(LL)x*y;
}
LL query(int x){
	LL ans=0;
	for(int i=x;i>0;i-=i&(-i)){
		ans+=(x+1)*c1[i]-c2[i];
	}
	return ans;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)scanf("%llu",a+i),sum[i]=sum[i-1]+a[i];
	int pos,a,b;LL c;
	while(m--){
		scanf("%d%d%d",&pos,&a,&b);
		if(pos==1){
			scanf("%llu",&c);
			update(a,c),update(b+1,-c);
		}else{
			printf("%llu\n",query(b)-query(a-1)+sum[b]-sum[a-1]);
		}
	}
	return 0;
}