!因为POJ炸了所以这篇代码还没有试过能不能AC!!很难受啊!!
以前以为二维线段树非常神奇,实际接触后发现和一维线段树好像差不多,有点类似一个大线段树(x坐标)维护每一列的信息,每一列又是一个小线段树(y坐标),这就是线段树套线段树了,然后在网上终于找到了一篇和我以前写的一维线段树代码风格相近的代码,因为那篇博客也没什么注释讲解的,不过凭借对一维线段树的理解直接看代码还是比较好理解的,自己修补了许多改成了自己最熟悉也比较易懂的代码风格。
PS:这方面网上写的好的教程我还真没找到,只能靠多看来自己脑补了。
POJ 2155
给定一个01矩阵初始化所有元素为0,两种操作,一种给x1, y1, x2, y2四个坐标即两个点确定一个矩形将里面的值全部取反,一种给两个坐标x, y即一个点输出该点的值。
1 #include <iostream> 2 #include <string.h> 3 #include <cstdio> 4 #include <vector> 5 #include <queue> 6 #include <math.h> 7 #include <string> 8 #include <algorithm> 9 #include <time.h> 10 11 #define SIGMA_SIZE 26 12 #define lson rt<<1 13 #define rson rt<<1|1 14 #define lowbit(x) (x&-x) 15 #define foe(i, a, b) for(int i=a; i<=b; i++) 16 #define fo(i, a, b) for(int i = a; i < b; i++); 17 #pragma warning ( disable : 4996 ) 18 19 using namespace std; 20 typedef long long LL; 21 inline LL LMax(LL a,LL b) { return a>b?a:b; } 22 inline LL LMin(LL a,LL b) { return a>b?b:a; } 23 inline LL lgcd( LL a, LL b ) { return b==0?a:lgcd(b,a%b); } 24 inline LL llcm( LL a, LL b ) { return a/lgcd(a,b)*b; } //a*b = gcd*lcm 25 inline int Max(int a,int b) { return a>b?a:b; } 26 inline int Min(int a,int b) { return a>b?b:a; } 27 inline int gcd( int a, int b ) { return b==0?a:gcd(b,a%b); } 28 inline int lcm( int a, int b ) { return a/gcd(a,b)*b; } //a*b = gcd*lcm 29 const LL INF = 0x3f3f3f3f3f3f3f3f; 30 const LL mod = 1000000007; 31 const double eps = 1e-8; 32 const int inf = 0x3f3f3f3f; 33 const int maxk = 1e6+5; 34 const int maxn = 4005; 35 36 37 int N, Q, ans; 38 bool g[maxn][maxn]; 39 40 void init() 41 { 42 cin >> N >> Q; 43 memset(g, false, sizeof(g)); 44 } 45 46 void y_update(int xrt, int yrt, int lhs, int rhs, int L, int R ) 47 { 48 if ( lhs <= L && rhs >= R) 49 { 50 g[xrt][yrt] ^= 1; 51 return; 52 } 53 54 int mid = (L+R)>>1; 55 if ( lhs <= mid ) y_update(xrt, yrt<<1, lhs, rhs, L, mid); 56 if ( rhs > mid ) y_update(xrt, yrt<<1|1, lhs, rhs, mid+1, R); 57 } 58 59 void x_update(int xrt, int L, int R, int x1, int y1, int x2, int y2) 60 { 61 if ( x1 <= L && x2 >= R ) 62 { 63 y_update(xrt, 1, y1, y2, 1, N); 64 return; 65 } 66 67 int mid = (L+R)>>1; 68 if ( x1 <= mid ) x_update(xrt<<1, L, mid, x1, y1, x2, y2); 69 if ( x2 > mid ) x_update(xrt<<1|1, mid+1, R, x1, y1, x2, y2); 70 } 71 72 void y_query(int xrt, int yrt, int L, int R, int y1) 73 { 74 ans ^= g[xrt][yrt]; 75 if ( L == R ) 76 return; 77 78 int mid = (L+R)>>1; 79 if ( y1 <= mid ) y_query(xrt, yrt<<1, L, mid, y1); 80 else y_query(xrt, yrt<<1|1, mid+1, R, y1); 81 } 82 83 //注意查找的操作 84 void x_query(int xrt, int L, int R, int x1, int y1) 85 { 86 y_query(xrt, 1, 1, N, y1); 87 if ( L == R ) 88 return; 89 90 int mid = (L+R)>>1; 91 if ( x1 <= mid ) x_query(xrt<<1, L, mid, x1, y1); 92 else x_query(xrt<<1|1, mid+1, R, x1, y1); 93 } 94 95 int main() 96 { 97 int all; cin >> all; 98 while (all--) 99 { 100 init(); 101 102 char str[3]; 103 int x1, y1, x2, y2; 104 foe(i, 1, Q) 105 { 106 scanf("%s", str); 107 if (str[0] == 'C') 108 { 109 scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 110 x_update(1, 1, N, x1, y1, x2, y2); 111 } 112 else 113 { 114 scanf("%d %d", &x1, &y1); 115 ans = 0; 116 x_query(1, 1, N, x1, y1); 117 printf("%d\n", ans); 118 } 119 } 120 } 121 122 return 0; 123 }