poj 1195 Mobile phones(二维树状数组)
树状数组支持两种操作:
Add(x, d)操作: 让a[x]增加d。
Query(L,R): 计算 a[L]+a[L+1]……a[R]。
当要频繁的对数组元素进行修改,同时又要频繁的查询数组内任一区间元素之和的时候,可以考虑使用树状数组.
通常对一维数组最直接的算法可以在O(1)时间内完成一次修改,但是需要O(n)时间来进行一次查询.而树状数组的修改和查询均可在O(log(n))的时间内完成.
在二维情况下:数组A[][]的树状数组定义为:
C[x][y] = ∑ a[i][j], 其中,
x-lowbit(x) + 1 <= i <= x,
y-lowbit(y) + 1 <= j <= y.
学习网站:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804
题目:http://poj.org/problem?id=1195
题意:输入3的时候,结束。输入1对(x,y)加A....
输入3的时候,输出子矩阵从(L,B)到 (R,T)的和。。。
题目下标是从0开始的,所有要加1.。。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespace std; 7 const int maxn = 1050; 8 int n,c[maxn][maxn]; 9 10 int lowbit(int x) 11 { 12 return x&(-x); 13 } 14 void add(int x,int y,int d) 15 { 16 int i,j; 17 for(i = x; i <= n; i += lowbit(i)) 18 for(j = y; j <= n; j += lowbit(j)) 19 c[i][j] += d; 20 } 21 int sum(int x,int y) 22 { 23 int i,j,ret = 0; 24 for(i = x; i > 0; i -=lowbit(i)) 25 for(j = y; j > 0; j -= lowbit(j)) 26 ret += c[i][j]; 27 return ret; 28 } 29 30 int main() 31 { 32 int X,Y,A,t; 33 int L,B,R,T; 34 while(cin>>T) 35 { 36 cin>>n; 37 memset(c,0,sizeof(0)); 38 while(cin>>t) 39 { 40 if(t == 3)break; 41 else if(t == 1) 42 { 43 scanf("%d%d%d",&X,&Y,&A); 44 add(X + 1,Y + 1,A); 45 } 46 else if(t == 2) 47 { 48 scanf("%d%d%d%d",&L,&B,&R,&T); 49 printf("%d\n",sum(R+1,T+1)-sum(R+1,B)-sum(L,T+1)+sum(L,B)); 50 } 51 } 52 } 53 return 0; 54 }
模板:
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 using namespace std; 7 const int maxn = 1050; 8 int n,c[maxn][maxn]; 9 10 int lowbit(int x) 11 { 12 return x&(-x); 13 } 14 void add(int x,int y,int d) 15 { 16 int i,j; 17 for(i = x; i <= n; i += lowbit(i)) 18 for(j = y; j <= n; j += lowbit(j)) 19 c[i][j] += d; 20 } 21 int sum(int x,int y) 22 { 23 int i,j,ret = 0; 24 for(i = x; i > 0; i -=lowbit(i)) 25 for(j = y; j > 0; j -= lowbit(j)) 26 ret += c[i][j]; 27 return ret; 28 } 29 30 int main() 31 { 32 int i,j,x; 33 int a,b,c,d; 34 cin>>n; 35 for(i = 1; i <= n; i++) 36 { 37 for(j = 1; j <= n; j++) 38 { 39 cin>>x; 40 add(i,j,x); 41 } 42 } 43 44 while(1) 45 { 46 cin>>a>>b>>c>>d; 47 cout<<(sum(c,d) - sum(c,b-1) - sum(a-1,d) + sum(a-1,b-1))<<endl; 48 } 49 50 return 0; 51 }