@@ -161,6 +161,12 @@ class BB
161
161
}
162
162
}
163
163
164
+ Real val_for_comp (const int &axis) const
165
+ {
166
+ const int axis2 = (axis + 1 ) % (2 * D);
167
+ return values[axis] + values[axis2];
168
+ }
169
+
164
170
BB operator +(const BB &rhs) const
165
171
{
166
172
Real result[2 * D];
@@ -189,18 +195,28 @@ class BB
189
195
}
190
196
}
191
197
192
- inline bool operator ()(const BB &target) const
198
+ bool operator ()(const BB &target) const
193
199
{ // whether this and target has any intersect
200
+
201
+ Real minima[D];
202
+ Real maxima[D];
203
+ bool flags[D];
204
+ bool flag = true ;
205
+
194
206
for (int i = 0 ; i < D; ++i)
195
207
{
196
- Real m = std::min (values[i], target.values [i]);
197
- Real M = std::min (values[i + D], target.values [i + D]);
198
- if (-m > M)
199
- {
200
- return false ;
201
- }
208
+ minima[i] = std::min (values[i], target.values [i]);
209
+ maxima[i] = std::min (values[i + D], target.values [i + D]);
210
+ }
211
+ for ( int i = 0 ; i < D; ++i)
212
+ {
213
+ flags[i] = -minima[i] < maxima[i];
202
214
}
203
- return true ;
215
+ for (int i = 0 ; i < D; ++i)
216
+ {
217
+ flag &= flags[i];
218
+ }
219
+ return flag;
204
220
}
205
221
206
222
Real area () const
@@ -257,10 +273,10 @@ template <class T, int B = 6, int D = 2>
257
273
class Leaf
258
274
{
259
275
public:
260
- int axis = 0 ;
261
- Real min_val = 1e100 ;
262
276
BB<D> mbb;
263
277
svec<DataType<T, D>, B> data; // You can swap when filtering
278
+ int axis = 0 ;
279
+
264
280
// T is type of keys(ids) which will be returned when you post a query.
265
281
Leaf ()
266
282
{
@@ -283,41 +299,36 @@ class Leaf
283
299
void update_mbb ()
284
300
{
285
301
mbb.clear ();
286
- min_val = 1e100 ;
287
302
for (const auto &datum : data)
288
303
{
289
304
mbb += datum.second ;
290
- min_val = std::min (min_val, datum.second [axis]);
291
305
}
292
306
}
293
307
294
- inline auto find_swapee ()
295
- {
296
- auto it = std::min_element (data.begin (), data.end (), [&](const auto &a, const auto &b) noexcept
297
- { return a.second [axis] < b.second [axis]; });
298
- return it;
299
- }
300
-
301
308
bool filter (DataType<T, D> &value)
302
309
{ // false means given value is ignored
310
+ auto comp = [=](const auto &a, const auto &b) noexcept
311
+ { return a.second .val_for_comp (axis) < b.second .val_for_comp (axis); };
312
+
303
313
if (data.size () < B)
304
314
{ // if there is room, just push the candidate
305
- data.push_back (value);
315
+ auto iter = std::lower_bound (data.begin (), data.end (), value, comp);
316
+ DataType<T, D> tmp_value = DataType<T, D>(value);
317
+ data.insert (iter, std::move (tmp_value));
306
318
mbb += value.second ;
307
- min_val = std::min (min_val, value.second [axis]);
308
319
return true ;
309
320
}
310
321
else
311
322
{ // if there is no room, check the priority and swap if needed
312
- /*
313
- auto iter = std::upper_bound(data.begin(), data.end(), value, [&](const auto &a, const auto &b) noexcept
314
- { return a.second[axis] < b.second[axis]; });
315
- if (iter != data.end())
316
- */
317
- if (min_val < value.second [axis])
323
+ if (data[0 ].second .val_for_comp (axis) < value.second .val_for_comp (axis))
318
324
{
319
- auto iter = find_swapee ();
320
- std::swap (*iter, value);
325
+ size_t n_swap = std::lower_bound (data.begin (), data.end (), value, comp) - data.begin ();
326
+ std::swap (*data.begin (), value);
327
+ auto iter = data.begin ();
328
+ for (size_t i = 0 ; i < n_swap - 1 ; ++i)
329
+ {
330
+ std::swap (*(iter + i), *(iter + i + 1 ));
331
+ }
321
332
update_mbb ();
322
333
}
323
334
return false ;
@@ -1230,9 +1241,8 @@ class PRTree
1230
1241
X.push_back (std::move (bb));
1231
1242
}
1232
1243
}
1233
- T length = X.size ();
1234
1244
vec<vec<T>> out;
1235
- out.reserve (length );
1245
+ out.reserve (X. size () );
1236
1246
#ifdef MY_DEBUG
1237
1247
std::for_each (X.begin (), X.end (),
1238
1248
[&](const BB<D> &x)
0 commit comments