M.J的blog

algorithm,ACM-ICPC
随笔 - 39, 文章 - 11, 评论 - 20, 引用 - 0
数据加载中……

POJ 1195 Mobile phones【二维树状数组】

简单的二维树状数组,求一个矩形区域内的和,因为要随时增减,而且可能减的数比原来都大,所以需要保留原来的数组。
在求矩形区域和的时候,只要用最大的矩形减去两个小的,再加上那个多减的最小的,就OK了。1y~~
Code:
 1 #include<iostream>
 2 #define M 1300
 3 int c[M][M],a[M][M],n;
 4 int lowbit(int t){
 5     return t&(t^(t-1));
 6 }
 7 int sum(int p,int q){
 8     int x=p,y,total=0;
 9     while(x>0){
10         y=q;
11         while(y>0){
12             total+=c[x][y];
13             y-=lowbit(y);
14         }
15         x-=lowbit(x);
16     }
17     return total;
18 }
19 void modify(int p,int q,int key){
20     int x=p,y;
21     while(x<=n){
22         y=q;
23         while(y<=n){
24             c[x][y]+=key;
25             y+=lowbit(y);
26         }
27         x+=lowbit(x);
28     }
29 }
30 int main()
31 {
32     int i,j,k,jj,kk,m,order,ans;
33     scanf("%d%d",&i,&n);
34     memset(c,0,sizeof(c));
35     memset(a,0,sizeof(a));
36     while(scanf("%d",&order)!=EOF){
37         if(order==3break;
38         else if(order==1){
39             scanf("%d%d%d",&j,&k,&m);
40             ++j;  ++k;
41             if(m<0&&m*(-1)>a[j][k]){
42                 m=(-1)*a[j][k];
43                 modify(j,k,m);
44                 a[j][k]=0;
45             }
46             else{
47                 modify(j,k,m);
48                 a[j][k]+=m;
49             }
50         }
51         else if(order==2){
52             scanf("%d%d%d%d",&j,&jj,&k,&kk);
53             ++j; ++jj; ++k; ++kk;
54             //printf("%d ",sum(n,n));
55             ans=sum(k,kk)+sum(j-1,jj-1)-sum(k,jj-1)-sum(j-1,kk);
56             printf("%d\n",ans);
57         }
58     }
59 }

posted on 2010-05-03 00:14 M.J 阅读(291) 评论(0)  编辑 收藏 引用 所属分类: 树状数组


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理