二维数据结构---线段树

!因为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 }
View Code

猜你喜欢

转载自www.cnblogs.com/chaoswr/p/9359556.html
今日推荐