POJ2155Matrix(二维线段树)

链接http://poj.org/problem?id=2155

题目操作就是说,每次操作可以是编辑某个矩形区域,这个区域的0改为1,1改为0,每次查询只查询某一个点的值是0还是1.

方法:二维线段树,这个东东我纠结了好久才慢慢弄好。二维线段树其实就就是在第一位区间的每个节点下再建一颗线段树,表示第二维的区间。

在修改的时候只需要先找到第一维的对应区间,在在这个区间的弟二维中查找对应区间,再做修改即可。而查找的时候,由于不同的第一维区间可能会有包含关系,所以需要对每个目标所在第一维区间查找第二维区间。

比如线段树的区间大小是3×3,那么在查找第一维区间是[1,2],第二维区间是[1,2]时,就需要在线段树第一维的[1,3]和[1,2]两个区间对第二维进行查找,因为修改操作的时候可能修改了第一维的[1,3]区间,同时也修改了[1,2]区间,这样的话就不能仅仅只查找某一个第一维的区间。

至于本题的解法,我们可以在修改时标记某一个节点,那么这个节点以下的区间就都是要修改的,当我们在查找的时候,只需要统计查找到这个点时,一路上有多少个被修改的区间,是偶数说明呗修改回来了,是奇数那就是被修改了。

 1 #include <stdio.h>
 2 #include <string.h>
 3 #define xlson kx<<1, xl, mid
 4 #define xrson kx<<1|1, mid+1, xr
 5 #define ylson ky<<1, yl, mid
 6 #define yrson ky<<1|1, mid+1, yr
 7 #define MAXN 1005
 8 #define mem(a) memset(a, 0, sizeof(a))
 9 
10 bool tree[MAXN<<2][MAXN<<2];
11 int  X, N, T;
12 int num, X1, X2, Y1, Y2;
13 char ch;
14 
15 void editY(int kx,int ky,int yl,int yr)
16 {
17     if(Y1<=yl && yr<=Y2)
18     {
19         tree[kx][ky] = !tree[kx][ky];
20         return ;
21     }
22     int mid = (yl+yr)>>1;
23     if(Y1 <= mid) editY(kx,ylson);
24     if(Y2 >  mid) editY(kx,yrson);
25 }
26 
27 void editX(int kx,int xl,int xr)
28 {
29     if(X1<=xl && xr<=X2)
30     {
31         editY(kx,1,1,N);
32         return ;
33     }
34     int mid = (xl+xr)>>1;
35     if(X1 <= mid) editX(xlson);
36     if(X2 >  mid) editX(xrson);
37 }
38 
39 void queryY(int kx,int ky,int yl,int yr)
40 {
41     if(tree[kx][ky]) num ++;
42     if(yl==yr) return ;
43     int mid = (yl+yr)>>1;
44     if(Y1 <= mid) queryY(kx,ylson);
45     else queryY(kx,yrson);
46 }
47 
48 void queryX(int kx,int xl,int xr)
49 {
50     queryY(kx,1,1,N);
51     if(xl==xr) return ;
52     int mid = (xl+xr)>>1;
53     if(X1 <= mid)queryX(xlson);
54     else  queryX(xrson);
55 }
56 
57 
58 int main()
59 {
60     while(~scanf("%d", &X))while(X--)
61     {
62         mem(tree);
63         scanf("%d %d%*c", &N,&T);
64         for(int i=0;i<T;i++)
65         {
66             scanf("%c %d %d%*c",&ch,&X1,&Y1);
67             if(ch == 'C')
68             {
69                 scanf("%d %d%*c", &X2, &Y2);
70                 editX(1,1,N);
71             }
72             else
73             {
74                 num = 0;
75                 queryX(1,1,N);
76                 if(num & 1)printf("1\n");
77                 else printf("0\n");
78             }
79         }
80         if(X) printf("\n");
81     }
82     return 0;
83 }

 

posted @ 2013-08-15 09:05  再见~雨泉  阅读(8115)  评论(0编辑  收藏  举报