• BZOJ2648 SJY摆棋子


    貌似和那道天使玩偶是一样的题?哇是不是有双倍经验辣!

    是一道"裸"的kd_tree,虽然。。。要维护的东西比较多,而且是2d_tree

    这题的估价函数的话,要维护每个点的子树形成的平面

      1 /**************************************************************
      2     Problem: 2648
      3     User: rausen
      4     Language: C++
      5     Result: Accepted
      6     Time:8108 ms
      7     Memory:60380 kb
      8 ****************************************************************/
      9  
     10 #include <cstdio>
     11 #include <algorithm>
     12  
     13 using namespace std;
     14 const int inf = 0x7f7f7f7f;
     15 const int N = 500005;
     16 const int Cnt_kd = N << 1;
     17 const int Maxlen = N * 5 * 10;
     18  
     19 int n, ans, Dep;
     20 char buf[Maxlen], *c = buf;
     21 int Len;
     22  
     23 inline int read() {
     24   int x = 0, sgn = 1;
     25   while (*c < '0' || '9' < *c) {
     26     if (*c == '-') sgn = -1; 
     27     ++c;
     28   }
     29   while ('0' <= *c && *c <= '9')
     30     x = x * 10 + *c - '0', ++c;
     31   return sgn * x;
     32 }
     33  
     34 struct point {
     35   int x[2];
     36  
     37   point(int _x0 = 0, int _x1 = 0) : x({_x0, _x1}) {}
     38   inline int& operator [] (int i) {
     39     return x[i];
     40   }
     41   inline bool operator < (const point &p) const {
     42     return x[Dep] < p.x[Dep];
     43   }
     44   inline void read_in() {
     45     x[0] = read(), x[1] = read();
     46   }
     47 } points[N];
     48  
     49  
     50 struct kd_node {
     51   kd_node *ls, *rs;
     52   int mx[2], mn[2];
     53   point p;
     54 } *kd_root, mempool[Cnt_kd], *cnt_kd = mempool, *null;
     55  
     56 inline int dis(point p, point q) {
     57   return abs(p[0] - q[0]) + abs(p[1] - q[1]);
     58 }
     59  
     60 #define Ls p -> ls
     61 #define Rs p -> rs
     62 #define Mx p -> mx
     63 #define Mn p -> mn
     64 #define P p -> p
     65 inline void kd_new(kd_node *&p, point p1) {
     66   int i;
     67   p = ++cnt_kd;
     68   Ls = Rs = null, P = p1;
     69   for (i = 0; i < 2; ++i)
     70     Mx[i] = Mn[i] = P[i];
     71 }
     72  
     73 inline int dist(kd_node *p, point p1) {
     74   int res = 0, i;
     75   for (i = 0; i < 2; ++i)
     76     res += max(0, Mn[i] - p1[i]);
     77   for (i = 0; i < 2; ++i)
     78     res += max(0, p1[i] - Mx[i]);
     79   return res;
     80 }
     81  
     82 inline void kd_update(kd_node *p) {
     83   int i;
     84   for (i = 0; i < 2; ++i) {
     85     if (Ls != null) {
     86       Mn[i] = min(Mn[i], Ls -> mn[i]);
     87       Mx[i] = max(Mx[i], Ls -> mx[i]);
     88     }
     89     if (Rs != null) {
     90       Mn[i] = min(Mn[i], Rs -> mn[i]);
     91       Mx[i] = max(Mx[i], Rs -> mx[i]);
     92     }
     93   }
     94 }
     95  
     96 #define mid (l + r >> 1)
     97 inline void kd_build(kd_node *&p, int l, int r, int d) {
     98   Dep = d;
     99   nth_element(points + l, points + mid, points + r + 1);
    100   kd_new(p, points[mid]);
    101   if (l < mid) kd_build(Ls, l, mid - 1, !d);
    102   if (mid < r) kd_build(Rs, mid + 1, r, !d);
    103   kd_update(p);
    104 }
    105 #undef mid
    106  
    107 void kd_insert(kd_node *&p, point p1, int d) {
    108   if (p == null) {
    109     kd_new(p, p1);
    110     return;
    111   }
    112   if (P[d] > p1[d]) kd_insert(Ls, p1, !d);
    113   else kd_insert(Rs, p1, !d);
    114   kd_update(p);
    115 }
    116  
    117 void kd_query(kd_node *p, point p1, int d) {
    118   int dl, dr;
    119   ans = min(ans, dis(P, p1));
    120   dl = (Ls == null ? inf : dist(Ls, p1));
    121   dr = (Rs == null ? inf : dist(Rs, p1));
    122   if (dl < dr) {
    123     if (dl < ans) kd_query(Ls, p1, !d);
    124     if (dr < ans) kd_query(Rs, p1, !d);
    125   } else {
    126     if (dr < ans) kd_query(Rs, p1, !d);
    127     if (dl < ans) kd_query(Ls, p1, !d);    
    128   }
    129 }
    130 #undef Ls
    131 #undef Rs
    132 #undef Mx
    133 #undef Mn
    134 #undef P
    135  
    136 int main() {
    137   Len = fread(c, 1, Maxlen, stdin);
    138   buf[Len] = '';
    139   int i, Q, oper, x, y;
    140   point P;
    141   n = read(), Q = read();
    142   null = cnt_kd;
    143   null -> ls = null -> rs = null;
    144   kd_root = null;
    145   for (i = 1; i <= n; ++i)
    146     points[i].read_in();
    147   kd_build(kd_root, 1, n, 0);
    148   while (Q--) {
    149     oper = read(), P.read_in();
    150     if (oper == 1) kd_insert(kd_root, P, 0);
    151     else {
    152       ans = inf;
    153       kd_query(kd_root, P, 0);
    154       printf("%d
    ", ans);
    155     }
    156   }
    157   return 0;
    158 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    以用户、组织结构和权限为例,论如何将基于关系型数据库的设计简化
    spring InitializingBean接口
    DelegatingFilterProxy
    组织机构权限系统的实现(工作流)
    activiti 引擎 数据库设计说明书
    modeler与activiti进行整合
    流程引擎的API和服务基础
    广东程序员在加利福尼亚
    开源 -- 机器学习相关报道
    国内一些大公司的开源项目
  • 原文地址:https://www.cnblogs.com/rausen/p/4294131.html
Copyright © 2020-2023  润新知