二維線段樹之樹套樹

  1 //poj1195 二維線段樹之樹套樹
  2 // 先確定橫座標所在的區間並記錄該結點的編號p,然後再確定縱座標所在的區間並記錄該結點的編號cur,則tree[cur][p]爲目標區間。
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <cmath>
  7 #include <algorithm>
  8 #include <queue>
  9 #include <stack>
 10 #include <deque>
 11 #include <map>
 12 #include <iostream>
 13 using namespace std;
 14 typedef long long LL;
 15 const double pi = acos(-1.0);
 16 const double e = exp(1);
 17 //const int MAXN =2e5+10;
 18 const int N = 1055;
 19 
 20 //const int maxn = 1024 * 1024 * 1.5;
 21 
 22 int n;
 23 int sum[N * 3][N * 3];
 24 
 25 void updatey(int y, int l, int r, int cur, int p, int op, int val)
 26 // 縱座標目標值,待找區間的左端點,待找區間的右端點,y中樹的結點的下標,已找到的橫座標中結點的下標,值更新的方式,需要更新的值
 27 {
 28     if(l == r)
 29     {
 30         if(op == 1)  //根據題目要求,對目標值直接修改
 31         {
 32             sum[p][cur] += val;
 33         }
 34         else   // 回溯過程中,維護樹的結構
 35         {
 36             sum[p][cur] = sum[p << 1][cur] + sum[p << 1 | 1][cur];
 37         }
 38         return ;
 39     }
 40     int mid = (l + r) >> 1;
 41     if(y <= mid)   //當前結點的左孩子區間需要找
 42     {
 43         updatey(y, l, mid, cur << 1, p, op, val);
 44     }
 45     else  // 當前結點的右孩子區間需要找
 46     {
 47         updatey(y, mid + 1, r, cur << 1 | 1, p, op, val);
 48     }
 49     sum[p][cur] = sum[p][cur << 1] + sum[p][cur << 1 | 1];
 50 
 51 }
 52 
 53 void updatex(int x, int y, int l, int r, int cur, int val)
 54 {
 55     if(l == r)
 56     {
 57         updatey(y, 1, n, 1, cur, 1, val);   //鎖定了橫座標所在的結點cur,再去尋找縱座標所在的結點。
 58         return ; 
 59     }
 60     int mid = (l + r) >> 1;
 61     if(x <= mid)
 62     {
 63         updatex(x, y, l, mid, cur << 1, val);
 64     }
 65     else
 66     {
 67         updatex(x, y, mid + 1, r, cur << 1 | 1, val);
 68     }
 69     updatey(y, 1, n, 1, cur, 2, val);
 70 }
 71 
 72 int queryy(int ly, int ry, int l, int r, int cur, int p)
 73 {
 74     if(ly <= l && ry >= r)
 75     {
 76         return sum[p][cur];
 77     }
 78     int res = 0;
 79     int mid = (l + r) >> 1;
 80     if(ly <= mid)
 81     {
 82         res += queryy(ly, ry, l, mid, cur << 1, p);
 83     }
 84     if(ry > mid)
 85     {
 86         res += queryy(ly, ry, mid + 1, r, cur << 1 | 1, p);
 87     }
 88     return res;
 89 }
 90 
 91 int queryx(int lx, int rx, int ly, int ry, int l, int r, int cur)
 92 {
 93     int res = 0;
 94     if(lx <= l && rx >= r)
 95     {
 96         res = queryy(ly, ry, 1, n, 1, cur);
 97         return res;
 98     }
 99     int mid = (l + r) >> 1;
100     if(lx <= mid)
101     {
102         res += queryx(lx, rx, ly, ry, l, mid, cur << 1);
103     }
104     if(rx > mid)
105     {
106         res += queryx(lx, rx, ly, ry, mid + 1, r, cur << 1 | 1);
107     }
108     return res;
109 }
110 
111 
112 int main()
113 {
114     int i, j, t;
115     int x1, y1, x2, y2, c;
116 
117     while(scanf("%d",&t) != EOF)
118     {
119         if(t == 3)
120             break;
121         if(t == 0)
122         {
123             scanf("%d",&n);
124             n ++;
125             memset(sum, 0, sizeof(sum));
126         }
127         else if(t == 1)
128         {
129             scanf("%d%d%d", &x1, &y1, &c);
130             x1 ++, y1 ++;
131             updatex(x1, y1, 1, n, 1, c);
132         }
133         else if(t == 2)
134         {
135             scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
136             x1++, y1++, x2++, y2++;
137             printf("%d\n", queryx(x1, x2, y1, y2, 1, n, 1));
138         }
139     }
140 
141     return 0;
142 }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章