Advertisement
peltorator

KD tree

Oct 9th, 2021
1,031
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.55 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define sz(x) (static_cast<int>((x).size()))
  3.  
  4. using namespace std;
  5.  
  6. typedef long long ll;
  7. typedef long double ld;
  8.  
  9. mt19937 rnd(239);
  10.  
  11. const int N = 312345;
  12.  
  13. int DIM = 0;
  14.  
  15. struct Point {
  16.     int x = 0, y = 0, c = 0, ind = 0;
  17.  
  18.     Point(const Point& other) {
  19.         x = other.x;
  20.         y = other.y;
  21.         c = other.c;
  22.         ind = other.ind;
  23.     }
  24.  
  25.     Point(int _x = 0, int _y = 0, int _c = 0, int _ind = 0) {
  26.         x = _x;
  27.         y = _y;
  28.         c = _c;
  29.         ind = _ind;
  30.     }
  31.  
  32.     bool operator<(const Point& other) const {
  33.         if (DIM == 0) {
  34.             return make_pair(x, ind) < make_pair(other.x, other.ind);
  35.         } else {
  36.             return make_pair(y, ind) < make_pair(other.y, other.ind);
  37.         }
  38.     }
  39. };
  40.  
  41. ll dist(Point a, Point b) {
  42.     return 1LL * (a.x - b.x) * (a.x - b.x) + 1LL * (a.y - b.y) * (a.y - b.y);
  43. }
  44.  
  45. bool cmpx(const Point& a, const Point &b) {
  46.     return make_pair(a.x, a.ind) < make_pair(b.x, b.ind);
  47. }
  48.  
  49. bool cmpy(const Point& a, const Point &b) {
  50.     return make_pair(a.y, a.ind) < make_pair(b.y, b.ind);
  51. }
  52.  
  53. const ll INF = 1e18;
  54.  
  55. struct KDTree
  56. {
  57.     Point tree[4 * N];
  58.     int siz[4 * N];
  59.  
  60.     void build(vector<Point>& vec, int v, int l, int r, int depth) {
  61.         //cout << v << ' ' << l << ' ' << r << endl;
  62.         siz[v] = max(0, r - l);
  63.         if (l >= r) {
  64.             return;
  65.         }
  66.         int mid = (l + r) / 2;
  67.         DIM = (depth % 2);
  68.         //sort(vec.begin() + l, vec.begin() + r);
  69.         nth_element(vec.begin() + l, vec.begin() + mid, vec.begin() + r);
  70.         tree[v] = vec[mid];
  71.         build(vec, 2 * v, l, mid, depth + 1);
  72.         build(vec, 2 * v + 1, mid + 1, r, depth + 1);
  73.     }
  74.  
  75.     void build(vector<Point>& vec) {
  76.         build(vec, 1, 0, sz(vec), 0);
  77.     }
  78.  
  79.     void query(Point p, int v, int depth, Point& ans, ll& curdist) {
  80.         ll thisdist = dist(tree[v], p);
  81.  
  82.         bool go_left = (depth % 2 == 1 ? cmpy : cmpx)(p, tree[v]);
  83.         int first_call = 2 * v + (go_left ? 0 : 1);
  84.         int second_call = 2 * v + (go_left ? 1 : 0);
  85.         if (siz[first_call]) {
  86.             query(p, first_call, depth + 1, ans, curdist);
  87.         }
  88.         bool need_second_son = false;
  89.         if (curdist == INF) {
  90.             if (tree[v].c <= p.c) {
  91.                 ans = tree[v];
  92.                 curdist = thisdist;
  93.             }
  94.             need_second_son = true;
  95.         }
  96.         else {
  97.             if(make_pair(curdist, ans.ind) > make_pair(thisdist, tree[v].ind) && tree[v].c <= p.c) {
  98.                 ans = tree[v];
  99.                 curdist = thisdist;
  100.             }
  101.             ll dst = (depth % 2 == 1 ? tree[v].y - p.y : tree[v].x - p.x);
  102.             if (dst * dst < curdist) {
  103.                 need_second_son = true;
  104.             }
  105.         }
  106.         if (siz[second_call] && need_second_son) {
  107.             query(p, second_call, depth + 1, ans, curdist);
  108.         }
  109.     }
  110.  
  111.     Point query(Point p) {
  112.         Point ans;
  113.         ll curdist = INF;
  114.         query(p, 1, 0, ans, curdist);
  115.         return ans;
  116.     }
  117. } myKDTree;
  118.  
  119. int main()
  120. {
  121.    // freopen("input.txt", "r", stdin);
  122.     //freopen("output.txt", "w", stdout);
  123.     ios_base::sync_with_stdio(0); cin.tie(0);
  124.     int t;
  125.     cin >> t;
  126.     while (t--) {
  127.         int n, m;
  128.         cin >> n >> m;
  129.         vector<Point> vec;
  130.         for (int i = 0; i < n; i++) {
  131.                 int x, y, c;
  132.                 cin >> x >> y >> c;
  133.                 Point p{x, y, c, i};
  134.                 vec.push_back(p);
  135.         }
  136.         myKDTree.build(vec);
  137.         for (int i = 0; i < m; i++) {
  138.             int x, y, c;
  139.             cin >> x >> y >> c;
  140.             Point p{x, y, c, -1};
  141.             Point ans = myKDTree.query(p);
  142.             cout << ans.x << ' ' << ans.y << ' ' << ans.c << '\n';
  143.         }
  144.     }
  145.     return 0;
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement