zoukankan      html  css  js  c++  java
  • bzoj2648/2716 SJY摆棋子

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2648

    http://www.lydsy.com/JudgeOnline/problem.php?id=2716

    【题解】

    直接上kdtree

    用查询的最近最远点的那种写法。

    估价在上一篇博客。

    还不知道过了吗真是傻逼还有人卡评测我日

    重构的BLOCK选在最多点数的1/10左右即可。。

    成功垫底。

    我真是傻逼RE了好几发

    build后面和rebuild都要ret。。。

    # include <stdio.h>
    # include <string.h>
    # include <iostream> 
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 1e6 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    
    inline void gmin(int &x, int y) {if(x > y) x = y;}
    inline void gmax(int &x, int y) {if(x < y) x = y;}
    
    int D;
    struct node {
        int d[2], mi[2], mx[2], l, r;
        friend bool operator == (node a, node b) {
            return a.d[0] == b.d[0] && a.d[1] == b.d[1];
        }
        friend bool operator < (node a, node b) {
            return a.d[D] < b.d[D];
        }
    }a[M], t[M];
    
    # define ls T[x].l
    # define rs T[x].r
    
    int n, m;
    
    node tmp;
    struct KDT {
        node T[M];
        int siz, rt;
        inline void set() {
            rt = siz = 0;
        }
        inline int getdist(int x, int X, int Y) {
            return max(T[x].mi[0]-X, 0) + max(X-T[x].mx[0], 0) + max(T[x].mi[1]-Y, 0) + max(Y-T[x].mx[1], 0);
        }
        inline void up(int x) {
            for (int i=0; i<2; ++i) {
                T[x].mi[i] = T[x].mx[i] = T[x].d[i];
                if(ls) gmin(T[x].mi[i], T[ls].mi[i]);
                if(rs) gmin(T[x].mi[i], T[rs].mi[i]);
                if(ls) gmax(T[x].mx[i], T[ls].mx[i]);
                if(rs) gmax(T[x].mx[i], T[rs].mx[i]);
            }
        }
                
        inline int build(int l, int r, int d) {
            if(l>r) return 0;
            int mid = l+r>>1;
            D = d; nth_element(t+l, t+mid, t+r+1);
    //        printf("mid = %d
    ", mid);
            T[mid] = t[mid];
            T[mid].l = build(l, mid-1, d^1);
            T[mid].r = build(mid+1, r, d^1);
            up(mid);
    //        printf("%d [%d,%d], [%d,%d], (%d, %d)
    ", mid, T[mid].mi[0], T[mid].mx[0], T[mid].mi[1], T[mid].mx[1], T[mid].d[0], T[mid].d[1]);
    //        printf("   ls = %d, rs = %d
    ", T[mid].l, T[mid].r); 
            return mid;
        }
        
        inline void insert(int &x, int d) {
            if(!x) {
                x = ++siz;
                for (int i=0; i<2; ++i)
                    T[x].d[i] = T[x].mi[i] = T[x].mx[i] = tmp.d[i];
                T[x].l = 0, T[x].r = 0;
            }
            if(tmp == T[x]) return ;
            if(tmp.d[d] < T[x].d[d]) insert(ls, d^1);
            else insert(rs, d^1);
            up(x);
        }
        
        int ans;
        inline void query(int x, int X, int Y) {
            if(!x) return;
            int tmp = abs(T[x].d[0]-X) + abs(T[x].d[1]-Y), d[2];
            if(ls) d[0] = getdist(ls, X, Y); else d[0] = 2147483647;
            if(rs) d[1] = getdist(rs, X, Y); else d[1] = 2147483647; 
            gmin(ans, tmp);
            if(d[0] < d[1]) {
                if(d[0] < ans) query(ls, X, Y);
                if(d[1] < ans) query(rs, X, Y);
            } else {
                if(d[1] < ans) query(rs, X, Y);
                if(d[0] < ans) query(ls, X, Y);
            }
        }
        
        inline int query(int X, int Y) {
            ans = 2147483647;
            query(rt, X, Y);
            return ans;
        }
        
        inline int rebuild(int l, int r, int d) {
            if(l>r) return 0;
            int mid = l+r>>1;
            D = d; nth_element(t+l, t+mid, t+r+1);
            T[mid] = t[mid];
            T[mid].l = rebuild(l, mid-1, d^1);
            T[mid].r = rebuild(mid+1, r, d^1);
            up(mid);
            return mid;
        }
    }T; 
    
    int REBUILD_SIZE = 100000;
    
    inline bool cmp(node a, node b) {
        return a.d[0] < b.d[0] || (a.d[0] == b.d[0] && a.d[1] < b.d[1]);
    }
    
    int main() {
    //    freopen("bzoj2648.in", "r", stdin);
    //    freopen("bzoj2648.out", "w", stdout);
        scanf("%d%d", &n, &m);
        for (int i=1; i<=n; ++i) scanf("%d%d", &a[i].d[0], &a[i].d[1]);
        sort(a+1, a+n+1, cmp);
        int tn = 0;
        t[++tn] = a[1];
        for (int i=2; i<=n; ++i) 
             if(!(a[i] == a[i-1])) t[++tn] = a[i];
        n = tn; REBUILD_SIZE += n; T.siz = n;
        T.rt = T.build(1, n, 0);
        int opt, x, y;
        for (int test = 1; test <= m; ++test) {
            scanf("%d%d%d", &opt, &x, &y);
            if(opt == 1) {
                tmp.d[0] = x, tmp.d[1] = y;
                T.insert(T.rt, 0);
                if(T.siz == REBUILD_SIZE) {
                    for (int i=1; i<=T.siz; ++i) t[i] = T.T[i];
                    T.rt = T.rebuild(1, T.siz, 0);
                    REBUILD_SIZE += 100000;
                }
            } else {
                printf("%d
    ", T.query(x, y));
            }
    //        cerr << "ok test = " << test << endl;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    浅浅地聊一下矩阵与线性映射及矩阵的特征值与特征向量
    再谈正态分布或高斯函数
    喜好:
    Deep Residual Learning for Image Recognition这篇文章
    Java并发编程:volatile关键字解析
    mysql decimal(10,2)对应java类型
    各个JSON技术的比较(Jackson,Gson,Fastjson)的对比
    @RequestBody和@RequestParam区别
    Java中的ReentrantLock和synchronized两种锁定机制的对比
    使用Solr索引MySQL数据
  • 原文地址:https://www.cnblogs.com/galaxies/p/bzoj2648.html
Copyright © 2011-2022 走看看