Matrix POJ 2155 Matrix

学习二维树状数组,线段树:

poj 2155 Matrix

题意: 给定一个n*n的0-1矩阵,执行一些如下的两种操作:
C a,b,c,d :将矩阵中(a,b)到(c,d)的格子中的0-1进行“非”操作
Q a b :询问当前(a,b)位置的元素的值

 二维树状数组

转化成:单点更新,成段求和。

一种思路是用一个二维数组tree[][]来标记数组中值的变换次数,通过变 换的次数就可以得出当前数组元素的值了。我们可以先分析一下一维时候的情况,假设一个一维的数组array[] ,现在要求给区间[a,b]内的每个元素增加一个值add,我们可以这样利用树状数组,将a元素增加add值,将(b+1)元素增加一个-add值,接下 去每次询问k位置的值的时候,只要将1-k位置的所有元素的值相加就是最后k位置的元素的值(PS:一开始元素的所有值都是0)。

 

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define size 1005
 4 int tree[size][size];
 5 int x,n,t;
 6 int lowbit(int k){
 7     return k&(-k);
 8 }
 9 
10 void add(int x,int y,int d){
11     int j;
12     while(x<=n){
13         j=y;
14         while(j<=n){
15             tree[x][j]+=d;
16             j+=lowbit(j);
17         }
18         x+=lowbit(x);
19     }
20 }
21 
22 int gsum(int x,int y){
23     int j,res=0;
24     while(x>0){
25         j=y;
26         while(j>0){
27             res+=tree[x][j];
28             j-=lowbit(j);
29         }
30         x-=lowbit(x);
31     }
32     return res;
33 }
34 
35 int main()
36 {
37     int x1,y1,x2,y2;
38     char s[3];
39    // freopen("test","r",stdin);
40     scanf("%d",&x);
41     for(int tt=0;tt<x;tt++){
42         if(tt!=0)
43             printf("\n");
44         scanf("%d%d",&n,&t);
45         memset(tree,0,sizeof(tree));
46         for(int i=0;i<t;i++){
47             scanf("%s",s);
48             if(s[0]=='C'){
49                 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
50                 add(x1,y1,1);
51                 add(x2+1,y1,-1);
52                 add(x1,y2+1,-1);
53                 add(x2+1,y2+1,1);
54             }
55             else{
56                 scanf("%d%d",&x1,&y1);
57                 int ans=gsum(x1,y1);
58                 if(ans%2==1)
59                     printf("1\n");
60                 else
61                     printf("0\n");
62             }
63         }
64     }
65     return 0;
66 }

 

 

二维线段树:

成段更新,单点查询;

View Code
 1 #include<stdio.h>
 2 #include<string.h>
 3 #define size 1010
 4 
 5 int sum[size<<2][size<<2];
 6 int n,q,ans;
 7 
 8 void build_y(int l,int r,int rt,int t){
 9     sum[t][rt]=0;
10     if(l==r)
11         return ;
12     int mid=(l+r)>>1;
13     build_y(l,mid,rt<<1,t);
14     build_y(mid+1,r,rt<<1|1,t);
15 }
16 void build_x(int l,int r,int rt){
17     build_y(1,n,1,rt);
18     if(l==r)
19         return ;
20     int mid=(l+r)>>1;
21     build_x(l,mid,rt<<1);
22     build_x(mid+1,r,rt<<1|1);
23 }
24 
25 void update_y(int Ly,int Ry,int l,int r,int rt,int t){
26     if(Ly<=l && Ry>=r){
27         sum[t][rt]^=1;
28         return ;
29     }
30     int mid=(l+r)>>1;
31     if(Ly<=mid)   update_y(Ly,Ry,l,mid,rt<<1,t);
32     if(Ry> mid)   update_y(Ly,Ry,mid+1,r,rt<<1|1,t);
33 }
34 void update_x(int Lx,int Rx,int Ly,int Ry,int l,int r,int rt){
35     if(Lx<=l && Rx>=r){
36         update_y(Ly,Ry,1,n,1,rt);
37         return ;
38     }
39     int mid=(l+r)>>1;
40     if(Lx<=mid) update_x(Lx,Rx,Ly,Ry,l,mid,rt<<1);
41     if(Rx> mid) update_x(Lx,Rx,Ly,Ry,mid+1,r,rt<<1|1);
42 }
43 
44 void query_y(int y,int l,int r,int rt,int t){
45     ans^=sum[t][rt];
46     if(l==r)
47         return;
48     int mid=(l+r)>>1;
49     if(y<=mid) query_y(y,l,mid,rt<<1,t);
50     else       query_y(y,mid+1,r,rt<<1|1,t);
51 }
52 void query(int x,int y,int l,int r,int rt){
53     query_y(y,1,n,1,rt);
54     if(l==r)
55         return ;
56     int mid=(l+r)>>1;
57     if(x<=mid) query(x,y,l,mid,rt<<1);
58     else       query(x,y,mid+1,r,rt<<1|1);
59 }
60 int main()
61 {
62     int x,i;
63     int x1,y1,x2,y2;
64     char s[3];
65  //   freopen("test","r",stdin);
66     scanf("%d",&x);
67     for(int tt=0;tt<x;tt++){
68         if(tt!=0)
69             printf("\n");
70         scanf("%d%d",&n,&q);
71         build_x(1,n,1);
72         for(i=0;i<q;i++){
73             scanf("%s",s);
74             if(s[0]=='C'){
75                 scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
76                 update_x(x1,x2,y1,y2,1,n,1);
77             }
78             else{
79                 scanf("%d%d",&x1,&y1);
80                 ans=0;
81                 query(x1,y1,1,n,1);
82                 printf("%d\n",ans);
83             }
84         }
85     }
86     return 0;
87 }

 

 

 

 

posted @ 2012-10-24 13:23  feng_linxu  Views(166)  Comments(0)    收藏  举报