你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:
命令
|
参数限制
|
内容
|
1 x y A
|
1<=x,y<=N,A是正整数
|
将格子x,y里的数字加上A
|
2 x1 y1 x2 y2
|
1<=x1<= x2<=N
1<=y1<= y2<=N
|
输出x1 y1 x2 y2这个矩形内的数字和
|
3
|
无
|
终止程序
|
输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。
数据规模和约定
1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。
样例解释见OJ2683
新加数据一组,但未重测----2015.05.24
1. 数据通过一定方式强制在线
2. 内存限制只有20M,二维数据结构基本被终结
显然是KD-Tree了,而且需要定期重建以保持其优秀的性质。看到有的题解没有重建就AC了,大概新加数据有卡这类程序,亦或者是大佬的KD-Tree十分优美吧,我等蒟蒻并无此功底……
因为数据以3作为输入终止信号,一开始并不知道有多少操作,也不知道操作是什么,我也懒得先存起来统计操作次数,所以需要找一个合适的重建限度,及进行多少次插入操作后,重建整个KD-Tree。要来数据在本地试了几个数字,发现这个限度取1500~2000较为合适(我一开始猜了个500,直接TLE了),虽然OJ和本地的测试环境有些差距吧,但还是可以作为参考,小伙伴可以像我一样取1700,OJ上跑了30S。
1 #include <cstdio>
2 #include <algorithm>
3
4 inline int getint(void)
5 {
6 int r = 0, f = 0, c = getchar();
7
8 for (; c < 48; c = getchar())
9 if (c == ‘-‘)f ^= 1;
10
11 for (; c > 47; c = getchar())
12 r = r * 10 + c - 48;
13
14 return f ? -r : r;
15 }
16
17 const int siz = 200005;
18
19 struct node
20 {
21 int val;
22 int sum;
23 int pos[2];
24 int son[2];
25 int mini[2];
26 int maxi[2];
27
28 inline void setup(int x, int y, int v)
29 {
30 val = sum = v;
31 son[0] = son[1] = 0;
32 pos[0] = mini[0] = maxi[0] = x;
33 pos[1] = mini[1] = maxi[1] = y;
34 }
35 }tr[siz]; int tot;
36
37 inline void update(int t)
38 {
39 tr[t].sum = tr[t].val;
40
41 if (tr[t].son[0])
42 tr[t].sum += tr[tr[t].son[0]].sum;
43 if (tr[t].son[1])
44 tr[t].sum += tr[tr[t].son[1]].sum;
45
46 tr[t].mini[0] = tr[t].maxi[0] = tr[t].pos[0];
47 tr[t].mini[1] = tr[t].maxi[1] = tr[t].pos[1];
48
49 for (int i = 0; i < 2; ++i)if (tr[t].son[i])
50 for (int j = 0; j < 2; ++j)
51 {
52 if (tr[t].mini[j] > tr[tr[t].son[i]].mini[j])
53 tr[t].mini[j] = tr[tr[t].son[i]].mini[j];
54 if (tr[t].maxi[j] < tr[tr[t].son[i]].maxi[j])
55 tr[t].maxi[j] = tr[tr[t].son[i]].maxi[j];
56 }
57 }
58
59 void insert(int &t, int p, int k)
60 {
61 if (!t)t = p;
62 else
63 {
64 if (tr[p].pos[k] <= tr[t].pos[k])
65 insert(tr[t].son[0], p, k ^ 1);
66 else
67 insert(tr[t].son[1], p, k ^ 1);
68
69 update(t);
70 }
71 }
72
73 int cmpk;
74
75 inline bool cmp(const node &a, const node &b)
76 {
77 if (a.pos[cmpk] != b.pos[cmpk])
78 return a.pos[cmpk] < b.pos[cmpk];
79 else
80 return a.pos[cmpk^1] < b.pos[cmpk^1];
81 }
82
83 int build(int l, int r, int k)
84 {
85 int mid = (l + r) >> 1; cmpk = k;
86
87 std::nth_element(tr + l, tr + mid, tr + r + 1, cmp);
88
89 tr[mid].son[0] = l < mid ? build(l, mid - 1, k ^ 1) : 0;
90 tr[mid].son[1] = r > mid ? build(mid + 1, r, k ^ 1) : 0;
91
92 return update(mid), mid;
93 }
94
95 int x1, y1, x2, y2, ans;
96
97 inline bool none(int t)
98 {
99 return
100 x1 > tr[t].maxi[0]
101 || x2 < tr[t].mini[0]
102 || y1 > tr[t].maxi[1]
103 || y2 < tr[t].mini[1];
104 }
105
106 inline bool have(int t)
107 {
108 return
109 x1 <= tr[t].mini[0]
110 && x2 >= tr[t].maxi[0]
111 && y1 <= tr[t].mini[1]
112 && y2 >= tr[t].maxi[1];
113 }
114
115 inline bool in(int t)
116 {
117 return
118 x1 <= tr[t].pos[0]
119 && x2 >= tr[t].pos[0]
120 && y1 <= tr[t].pos[1]
121 && y2 >= tr[t].pos[1];
122 }
123
124 void query(int t)
125 {
126 if (none(t))return;
127 if (have(t))ans += tr[t].sum;
128 else
129 {
130 if (in(t))ans += tr[t].val;
131 if (tr[t].son[0])query(tr[t].son[0]);
132 if (tr[t].son[1])query(tr[t].son[1]);
133 }
134 }
135
136 signed main(void)
137 {
138 // freopen("simple.in", "r", stdin);
139 // freopen("simple.out", "w", stdout);
140
141 int n = getint(), root = ++tot;
142
143 tr[root].setup(n >> 1, n >> 1, 0);
144
145 while (true)
146 {
147 int k = getint();
148
149 if (k == 1)
150 {
151 int x = getint() ^ ans;
152 int y = getint() ^ ans;
153 int v = getint() ^ ans;
154
155 tr[++tot].setup(x, y, v);
156
157 if (tot % 1700)
158 insert(root, tot, 0);
159 else
160 root = build(1, tot, 0);
161 }
162 else if (k == 2)
163 {
164 x1 = getint() ^ ans;
165 y1 = getint() ^ ans;
166 x2 = getint() ^ ans;
167 y2 = getint() ^ ans;
168
169 ans = 0; query(root);
170
171 printf("%d\n", ans);
172 }
173 else break;
174 }
175
176 // fclose(stdin);
177 // fclose(stdout);
178 }
179
180 /*
181 2000 : 18.02
182 1800 : 17.22
183 1700 : 16.89
184 1500 : 17.74
185 1000 : 20.80
186 900 : 22.53
187 700 : 25.08
188 500 : 33.55
189 300 : T L E
190 */