Advertisement
Emiliatan

b446

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