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 }