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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM