zoukankan      html  css  js  c++  java
  • BZOJ 2648: SJY摆棋子

    2648: SJY摆棋子

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 2968  Solved: 1011
    [Submit][Status][Discuss]

    Description

    这天,SJY显得无聊。在家自己玩。在一个棋盘上,有N个黑色棋子。他每次要么放到棋盘上一个黑色棋子,要么放上一个白色棋子,如果是白色棋子,他会找出距离这个白色棋子最近的黑色棋子。此处的距离是 曼哈顿距离 即(|x1-x2|+|y1-y2|) 。现在给出N<=500000个初始棋子。和M<=500000个操作。对于每个白色棋子,输出距离这个白色棋子最近的黑色棋子的距离。同一个格子可能有多个棋子。
     

    Input

    第一行两个数 N M
    以后M行,每行3个数 t x y
    如果t=1 那么放下一个黑色棋子
    如果t=2 那么放下一个白色棋子

    Output

    对于每个T=2 输出一个最小距离
     

    Sample Input

    2 3
    1 1
    2 3
    2 1 2
    1 3 3
    2 4 2

    Sample Output


    1
    2

    HINT

     

    kdtree可以过

    Source

    [Submit][Status][Discuss]

    既然题目都这么友好地告诉我们KD-Tree可解了,那就没理由不写KD-Tree了,对吧。( ̄_, ̄ )

    对于原本就存在的黑色棋子,那么就先读入,然后用build()建树;对于之后插入的黑色棋子,在insert()中根据KD-Tree的二叉树性质找到合适的叶子结点,插入即可。查询的时候,记得用最优性剪枝,并且合理利用估价函数,以避免TLE。

      1 #include <bits/stdc++.h>
      2 
      3 inline int next(void) {
      4     int ret = 0, neg = 0, bit = getchar();
      5     while (bit < '0') {
      6         if (bit == '-')
      7             neg ^= true;
      8         bit = getchar();
      9     }
     10     while (bit >= '0') {
     11         ret = ret*10 + bit - '0';
     12         bit = getchar();
     13     }
     14     return neg ? -ret : ret;
     15 }
     16 
     17 const int siz = 2e6 + 7;
     18 const int inf = 2e9 + 7;
     19 
     20 struct node {
     21     int pos[2];
     22     int son[2];
     23     int min[2];
     24     int max[2];
     25 }tree[siz];
     26 
     27 int root;
     28 int cmp_k;
     29 int qry_x;
     30 int qry_y;
     31 int answer;
     32 
     33 inline bool cmp(node a, node b) {
     34     return
     35         (a.pos[cmp_k] ^ b.pos[cmp_k])
     36     ?    (a.pos[cmp_k] < b.pos[cmp_k])
     37     :    (a.pos[!cmp_k] < b.pos[!cmp_k]);
     38 }
     39 
     40 inline void update(int t) {
     41     for (int i = 0; i < 2; ++i)if (tree[t].son[i])
     42         for (int j = 0; j < 2; ++j) {
     43             if (tree[t].min[j] > tree[tree[t].son[i]].min[j])
     44                 tree[t].min[j] = tree[tree[t].son[i]].min[j];
     45             if (tree[t].max[j] < tree[tree[t].son[i]].max[j])
     46                 tree[t].max[j] = tree[tree[t].son[i]].max[j];
     47         }
     48 }
     49 
     50 int build(int l, int r, int k) {
     51     int d = (l + r) >> 1; cmp_k = k;
     52     std::nth_element(
     53         tree + l + 1,
     54         tree + d + 1, 
     55         tree + r + 1, 
     56         cmp);
     57     if (l != d)tree[d].son[0] = build(l, d - 1, !k);
     58     if (r != d)tree[d].son[1] = build(d + 1, r, !k);
     59     tree[d].min[0] = tree[d].max[0] = tree[d].pos[0];
     60     tree[d].min[1] = tree[d].max[1] = tree[d].pos[1];
     61     return update(d), d;
     62 }
     63 
     64 inline void insert(int t) {
     65     for (int p = root, k = 0; p != t; k = !k) {
     66         for (int i = 0; i < 2; ++i) {
     67             if (tree[p].min[i] > tree[t].min[i])
     68                 tree[p].min[i] = tree[t].min[i];
     69             if (tree[p].max[i] < tree[t].max[i])
     70                 tree[p].max[i] = tree[t].max[i];
     71         }
     72         int &to = tree[p].son[tree[t].pos[k] >= tree[p].pos[k]];
     73         to = to ? to : t; p = to;
     74     }
     75 }
     76 
     77 inline int dist(int t) {
     78     if (!t)return inf;
     79     int ret = 0;
     80     if (qry_x < tree[t].min[0])
     81         ret += tree[t].min[0] - qry_x;
     82     if (qry_x > tree[t].max[0])
     83         ret += qry_x - tree[t].max[0];
     84     if (qry_y < tree[t].min[1])
     85         ret += tree[t].min[1] - qry_y;
     86     if (qry_y > tree[t].max[1])
     87         ret += qry_y - tree[t].max[1];
     88     return ret;
     89 }
     90 
     91 void query(int t) {
     92     answer = std::min(answer, 
     93         std::abs(tree[t].pos[0] - qry_x)
     94     +    std::abs(tree[t].pos[1] - qry_y));
     95     if (dist(tree[t].son[0]) < dist(tree[t].son[1])) {
     96         if (dist(tree[t].son[0]) < answer)query(tree[t].son[0]);
     97         if (dist(tree[t].son[1]) < answer)query(tree[t].son[1]);
     98     } else {
     99         if (dist(tree[t].son[1]) < answer)query(tree[t].son[1]);
    100         if (dist(tree[t].son[0]) < answer)query(tree[t].son[0]);
    101     }
    102 }
    103 
    104 signed main(void) {
    105     int n = next();
    106     int m = next();
    107     for (int i = 1; i <= n; ++i) {
    108         tree[i].pos[0] = next();
    109         tree[i].pos[1] = next();
    110     }
    111     root = build(1, n, 0);
    112     for (int i = 1; i <= m; ++i) {
    113         int k = next();
    114         int x = next();
    115         int y = next();
    116         if (k == 1) {
    117             ++n;
    118             tree[n].min[0] = tree[n].max[0] = tree[n].pos[0] = x;
    119             tree[n].min[1] = tree[n].max[1] = tree[n].pos[1] = y;
    120             insert(n);
    121         }
    122         else {
    123             qry_x = x;
    124             qry_y = y;
    125             answer = inf;
    126             query(root);
    127             printf("%d
    ", answer);
    128         }
    129     }
    130 }
    View Code

    @Author: YouSiki

  • 相关阅读:
    Spring 声明式事务管理(11)
    Spring JdbcTemplate详解(9)
    Spring 基于xml配置方式的AOP(8)
    Spring AspectJ 切入点语法详解(7)
    Spring 基于Aspectj切面表达式(6)
    spring AOP 编程--AspectJ注解方式 (4)
    Spring 切面优先级(5)
    Spring 泛型依赖注入(3)
    python反射/自省 (目前是转载)
    flask_requirements
  • 原文地址:https://www.cnblogs.com/yousiki/p/6130401.html
Copyright © 2011-2022 走看看