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 }