Advertisement
Emiliatan

kdt

Nov 24th, 2019
184
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.26 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef unsigned int uint;
  6. typedef long long int64;
  7. typedef unsigned long long uint64;
  8.  
  9. const int MAXD = 3;
  10.  
  11. class KDT
  12. {
  13.     public:
  14.         typedef struct point
  15.         {
  16.             int d[MAXD];
  17.             inline int dis(const point &to) const
  18.             {
  19.                 int res = 0;
  20.                 for(int i = 0; i < MAXD; ++i) res += abs(d[i] - to.d[i]);
  21.                 return res;
  22.             }
  23.             inline bool operator== (const point &p) const
  24.             {
  25.                 for(int i = 0; i < MAXD; ++i) if(d[i] != p.d[i]) return false;
  26.                 return true;
  27.             }
  28.             inline bool operator< (const point &p) const
  29.             {
  30.                 return d[0] < p.d[0];
  31.             }
  32.             inline void read()
  33.             {
  34.                 for(int i = 0; i < MAXD && scanf("%d", &d[i]); ++i);
  35.             }
  36.         }pt;
  37.     private:
  38.         struct node
  39.         {
  40.             node *l, *r;
  41.             pt pid;
  42.             int s;
  43.             node(const pt &p) : l(0), r(0), pid(p), s(1){}
  44.             void push_up()
  45.             {
  46.                 s = (l ? l -> s : 0) + 1 + (r ? r -> s : 0);
  47.             }
  48.         }*root;
  49.         struct __cmp
  50.         {
  51.             int sort_id;
  52.             inline bool operator()(const node *rhs, const node *lhs) const
  53.             {
  54.                 return operator()(rhs -> pid, lhs -> pid);
  55.             }
  56.             inline bool operator()(const pt &rhs, const pt &lhs) const
  57.             {
  58.                 if(rhs.d[sort_id] != lhs.d[sort_id]) return rhs.d[sort_id] < lhs.d[sort_id];
  59.                 for(int i = 0; i < MAXD; ++i)
  60.                     if(rhs.d[i] != lhs.d[i]) return rhs.d[i] < lhs.d[i];
  61.                 return false;
  62.             }
  63.         }cmp;
  64.  
  65.         vector<node*> A;
  66.         const double alpha, loga;
  67.         const int INF;
  68.         int maxn, qM;
  69.         priority_queue<pair<int, pt>> pq;
  70.  
  71.         void clear(node *x)
  72.         {
  73.             if(!x) return;
  74.             clear(x -> l);
  75.             clear(x -> r);
  76.             delete x;
  77.         }
  78.         inline int size(node *x)
  79.         {
  80.             return x ? x -> s : 0;
  81.         }
  82.  
  83.         node* build(int k, int l, int r)
  84.         {
  85.             if(l > r) return 0;
  86.  
  87.             int mid = (l + r) >> 1;
  88.  
  89.             k = (k == MAXD ? 0 : k);
  90.             cmp.sort_id = k;
  91.  
  92.             nth_element(A.begin() + l, A.begin() + mid, A.begin() + r + 1, cmp);
  93.  
  94.             node *res = A[mid];
  95.             res -> l = build(k + 1, l, mid - 1);
  96.             res -> r = build(k + 1, mid + 1, r);
  97.             res -> push_up();
  98.             return res;
  99.         }
  100.  
  101.         inline bool isBad(node *x)
  102.         {
  103.             return (size(x -> l) > alpha * x -> s) || (size(x -> r) > alpha * x -> s);
  104.         }
  105.  
  106.         void flatten(node *x, vector<node*>::iterator &it)
  107.         {
  108.             if(!x) return;
  109.             flatten(x -> l, it);
  110.             *it = x;
  111.             flatten(x -> r, ++it);
  112.         }
  113.  
  114.         inline void rebuild(node*&x, int k)
  115.         {
  116.             if((int)A.size() < x -> s) A.resize(x -> s);
  117.             typename vector<node*>::iterator it = A.begin();
  118.             flatten(x, it);
  119.             x = build(k, 0, x -> s - 1);
  120.         }
  121.  
  122.         bool insert(node*&x, int k, const point &taget, int dep)
  123.         {
  124.             if(!x)
  125.             {
  126.                 x = new node(taget);
  127.                 return dep <= 0;
  128.             }
  129.             ++(x -> s);
  130.             cmp.sort_id = k;
  131.             if(insert((cmp(taget, x -> pid) ? x -> l : x -> r), (k + 1) % MAXD, taget, dep - 1))
  132.             {
  133.                 if(!isBad(x)) return true;
  134.                 rebuild(x, k);
  135.             }
  136.             return false;
  137.         }
  138.         node *findmin(node *x, int k)
  139.         {
  140.             if(!x) return nullptr;
  141.             if(cmp.sort_id == k) return x -> l ? findmin(x -> l, (k + 1) % MAXD) : x;
  142.  
  143.             node *l = findmin(x -> l, (k + 1) % MAXD);
  144.             node *r = findmin(x -> r, (k + 1) % MAXD);
  145.  
  146.             if(l && !r) return cmp(l, x) ? l : x;
  147.             if(!l && r) return cmp(r, x) ? r : x;
  148.             if(!l && !r) return x;
  149.             if(cmp(l, r)) return cmp(l, x) ? l : x;
  150.             return cmp(r, x) ?  r : x;
  151.         }
  152.  
  153.         bool erase(node *&x, int k, const pt &taget)
  154.         {
  155.             if(!x) return false;
  156.  
  157.             if(x -> pid == taget)
  158.             {
  159.                 if(x -> r);
  160.                 else if(x -> l)
  161.                 {
  162.                     x -> r = x -> l;
  163.                     x -> l = 0;
  164.                 }
  165.                 else
  166.                 {
  167.                     delete x;
  168.                     x = nullptr;
  169.                     return true;
  170.                 }
  171.                 --(x -> s);
  172.                 cmp.sort_id = k;
  173.                 x -> pid = findmin(x -> r, (k + 1) % MAXD) -> pid;
  174.                 return erase(x -> r, (k + 1) % MAXD, x -> pid);
  175.             }
  176.  
  177.             cmp.sort_id = k;
  178.             if(erase((cmp(taget, x -> pid) ? x -> l : x -> r), (k + 1) % MAXD, taget)) {--(x -> s); return true;}
  179.             return false;
  180.         }
  181.         inline int heuristic(const int h[]) const
  182.         {
  183.             int res = 0;
  184.             for(int i = 0; i < MAXD; ++i) res += h[i];
  185.             return res;
  186.         }
  187.  
  188.         void nearest(node *x, int k, const pt &taget, int *h, int &mindis)
  189.         {
  190.             if(x == nullptr || heuristic(h) >= mindis) return;
  191.             int dist = x -> pid.dis(taget), tmp = h[k];
  192.  
  193.             if(dist < mindis && !(taget == x -> pid))
  194.             {
  195.                 pq.emplace(make_pair(dist, x -> pid));
  196.                 if((int)pq.size() == qM + 1)
  197.                     mindis = pq.top().first, pq.pop();
  198.             }
  199.             if(taget.d[k] < x -> pid.d[k])
  200.             {
  201.                 nearest(x -> l, (k + 1) % MAXD, taget, h, mindis);
  202.                 h[k] = abs(taget.d[k] - x -> pid.d[k]);
  203.                 nearest(x -> r, (k + 1) % MAXD, taget, h, mindis);
  204.             }
  205.             else
  206.             {
  207.                 nearest(x -> r, (k + 1) % MAXD, taget, h, mindis);
  208.                 h[k] = abs(taget.d[k] - x -> pid.d[k]);
  209.                 nearest(x -> l, (k + 1) % MAXD, taget, h, mindis);
  210.             }
  211.             h[k] = tmp;
  212.         }
  213.  
  214.     public:
  215.  
  216.         KDT(const int &INF, double a = 0.75) : root(nullptr), alpha(a), loga(log2(1.0 / a)), INF(INF), maxn(1){}
  217.         inline void clear()
  218.         {
  219.             clear(root), root = nullptr, maxn = 1;
  220.         }
  221.  
  222.         inline void build(int n, const pt *p)
  223.         {
  224.             clear(root), A.resize(maxn = n);
  225.             for(int i = 0; i < n; ++i) A[i] = new node(p[i]);
  226.             root = build(0, 0 ,n - 1);
  227.         }
  228.         inline void insert(const pt &x)
  229.         {
  230.             insert(root, 0, x, __lg(size(root)) / loga);
  231.             if(root -> s > maxn) maxn = root -> s;
  232.         }
  233.         inline bool erase(const pt &p)
  234.         {
  235.             bool d = erase(root, 0, p);
  236.             if(root && root -> s < alpha * maxn) rebuild();
  237.             return d;
  238.         }
  239.         inline void rebuild()
  240.         {
  241.             if(root) rebuild(root, 0);
  242.             maxn = root -> s;
  243.         }
  244.         inline int nearest(const pt &x, int k)
  245.         {
  246.             qM = k;
  247.             int mindis = INF, h[MAXD] = {};
  248.             nearest(root, 0, x, h, mindis);
  249.             if(pq.size())
  250.             {
  251.                 mindis = pq.top().first;
  252.                 pq = priority_queue<pair<int, pt> >();
  253.             }
  254.             assert(mindis >= 0);
  255.             return mindis;
  256.         }
  257.         inline int size()
  258.         {
  259.             return root ? root -> s : 0;
  260.         }
  261. };
  262.  
  263. int main()
  264. {
  265.     KDT kdt(INT_MAX);
  266.     KDT::point tmp;
  267.  
  268.     int n, op, k;
  269.  
  270.     scanf("%d", &n);
  271.  
  272.     while(n-- && scanf("%d", &op))
  273.     {
  274.         tmp.read();
  275.         switch(op)
  276.         {
  277.             case 0:
  278.                 scanf("%d", &k);
  279.                 if(k > kdt.size()) puts("(not found)");
  280.                 else printf("(%d)\n", kdt.nearest(tmp, k));
  281.                 break;
  282.             case 1:
  283.                 kdt.insert(tmp);
  284.                 break;
  285.             case 2:
  286.                 kdt.erase(tmp);
  287.                 break;
  288.         }
  289.     }
  290.  
  291.     return 0;
  292. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement