1. 程式人生 >實用技巧 >其它 >YbtOJ 樹狀陣列課堂過關 例5 單點修改區間查詢【二維樹狀陣列】

YbtOJ 樹狀陣列課堂過關 例5 單點修改區間查詢【二維樹狀陣列】


YbtOJ 樹狀陣列課堂過關 例5 單點修改區間查詢【二維樹狀陣列】


思路

這道題是二維樹狀陣列模板題。
直接維護 ∑ i = x 1 x 2 ∑ j = y 1 y 2 a i , j = ∑ i = 1 x 2 ∑ j = 1 y 2 a i , j − ∑ i = 1 x 1 − 1 ∑ j = 1 y 2 a i , j − ∑ i = 1 x 2 ∑ j = 1 y 1 − 1 a i , j + ∑ i = 1 x 1 − 1 ∑ j = 1 y 1 − 1 a i , j \sum_{i=x1}^{x2}\sum_{j=y1}^{y2}a_{i,j}=\sum_{i=1}^{x2}\sum_{j=1}^{y2}a_{i,j}-\sum_{i=1}^{x1-1}\sum_{j=1}^{y2}a_{i,j}-\sum_{i=1}^{x2}\sum_{j=1}^{y1-1}a_{i,j}+\sum_{i=1}^{x1-1}\sum_{j=1}^{y1-1}a_{i,j} i=x1∑x2​j=y1∑y2​ai,j​=i=1∑x2​j=1∑y2​ai,j​−i=1∑x1−1​j=1∑y2​ai,j​−i=1∑x2​j=1∑y1−1​ai,j​+i=1∑x1−1​j=1∑y1−1​ai,j​即可

程式碼

#include<iostream>
#include<cstdio>
using namespace std;
long long c[4100][4100];
long long n,m,w,a,b,cc,d;
long long lowbit(long long x)
{
	return x&-x;
}
void add(long long x,long long y,long long k)
{
	for(long long i=x; i<=n; i+=lowbit(i))
	 for(long long j=y; j<=m; j+=lowbit(j))
	    c[i][j]+=k;
}
long long sum(long long x,long long y)
{
	long long ans=0;
	for(long long i=x; i; i-=lowbit(i))
	 for(long long j=y; j; j-=lowbit(j))
	    ans+=c[i][j];
	return ans;
}
int main()
{
	cin>>n>>m;
	while(scanf("%lld",&w)!=EOF)
	 {
	 	if(w==1)
	 	 {
	 	 	scanf("%lld%lld%lld",&a,&b,&cc);
	 	 	add(a,b,cc);
		 }
		if(w==2)
		 {
		 	scanf("%lld%lld%lld%lld",&a,&b,&cc,&d);
		 	printf("%lld\n",sum(cc,d)-sum(a-1,d)-sum(cc,b-1)+sum(a-1,b-1));
		 }
	 }
	return 0;
}