• 【LG4169】[Violet]天使玩偶/SJY摆棋子


    【LG4169】[Violet]天使玩偶/SJY摆棋子

    题面

    洛谷

    题解

    至于(cdq)分治的解法,以前写过
    (kdTree)的解法好像还(sb)一些
    就是记一下子树的横、纵坐标最值然后求一下点到矩形得到距离
    之后再剪枝即可
    为什么不吸氧还是跑不过啊

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring> 
    #include <cmath> 
    #include <algorithm> 
    using namespace std; 
    inline int gi() {
        register int data = 0, w = 1;
        register char ch = 0;
        while (!isdigit(ch) && ch != '-') ch = getchar(); 
        if (ch == '-') w = -1, ch = getchar();
        while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar(); 
        return w * data; 
    }
    void chkmin(int &x, int y) { if (x > y) x = y; } 
    void chkmax(int &x, int y) { if (x < y) x = y; } 
    const int MAX_N = 1e6 + 5;
    const double alpha = 0.75;
    const int INF = 1e9; 
    struct Point { int x[2]; } p[MAX_N]; 
    struct Node {
        int mn[2], mx[2], ls, rs, size;
        Point tp; 
    } t[MAX_N]; 
    int N, M, rt, cur, top, WD, ans, rub[MAX_N];
    bool operator < (const Point &l, const Point &r) { return l.x[WD] < r.x[WD]; }
    int newnode() {
        if (top) return rub[top--]; 
        else return ++cur; 
    }
    void pushup(int o) {
        int ls = t[o].ls, rs = t[o].rs; 
        for (int i = 0; i <= 1; i++) {
            t[o].mn[i] = t[o].mx[i] = t[o].tp.x[i]; 
            if (ls) chkmin(t[o].mn[i], t[ls].mn[i]), chkmax(t[o].mx[i], t[ls].mx[i]); 
            if (rs) chkmin(t[o].mn[i], t[rs].mn[i]), chkmax(t[o].mx[i], t[rs].mx[i]); 
        }
        t[o].size = t[ls].size + t[rs].size + 1; 
    } 
    int build(int l, int r, int wd) {
        if (l > r) return 0; 
        int o = newnode(), mid = (l + r) >> 1; 
        WD = wd, nth_element(&p[l], &p[mid], &p[r + 1]), t[o].tp = p[mid]; 
        t[o].ls = build(l, mid - 1, wd ^ 1), t[o].rs = build(mid + 1, r, wd ^ 1);
        return pushup(o), o; 
    }
    void pia(int o, int num) { 
        if (t[o].ls) pia(t[o].ls, num);
        p[num + t[t[o].ls].size + 1] = t[o].tp, rub[++top] = o; 
        if (t[o].rs) pia(t[o].rs, num + t[t[o].ls].size + 1); 
    } 
    void check(int &o, int wd) {
        if (alpha * t[o].size < t[t[o].ls].size || alpha * t[o].size < t[t[o].rs].size) 
            pia(o, 0), o = build(1, t[o].size, wd); 
    }
    void insert(int &o, int wd, Point tmp) {
        if (!o) return (void)(o = newnode(), t[o].tp = tmp, t[o].ls = t[o].rs = 0, pushup(o));
        if (t[o].tp.x[wd] < tmp.x[wd]) insert(t[o].r
    91s, wd ^ 1, tmp); 
        else insert(t[o].ls, wd ^ 1, tmp); 
        pushup(o), check(o, wd); 
    }
    int getdis(int o, Point tmp) { 
        int res = 0;
        for (int i = 0; i <= 1; i++) res += max(0, tmp.x[i] - t[o].mx[i]) + max(0, t[o].mn[i] - tmp.x[i]);
        return res; 
    }
    int dist(Point a, Point b) { return abs(a.x[0] - b.x[0]) + abs(a.x[1] - b.x[1]); }
    void query(int o, Point tmp) { 
        ans = min(ans, dist(tmp, t[o].tp)); 
        int dl = INF, dr = INF; 
        if (t[o].ls) dl = getdis(t[o].ls, tmp); 
        if (t[o].rs) dr = getdis(t[o].rs, tmp);
        if (dl < dr) {
            if (dl < ans) query(t[o].ls, tmp); 
            if (dr < ans) query(t[o].rs, tmp); 
        } else {
            if (dr < ans) query(t[o].rs, tmp);
            if (dl < ans) query(t[o].ls, tmp); 
        } 
    }
    
    int main () {
        N = gi(), M = gi(); 
        for (int i = 1; i <= N; i++) p[i].x[0] = gi(), p[i].x[1] = gi();
        rt = build(1, N, 0);
        while (M--) {
            Point tmp;
            int op = gi(); tmp.x[0] = gi(), tmp.x[1] = gi();
            if (op == 1) insert(rt, 0, tmp);
            else ans = INF, query(rt, tmp), printf("%d
    ", ans); 
        } 
        return 0; 
    } 
    
  • 相关阅读:
    iOS汇编系列-汇编入门
    C开发系列-指针
    iOS开发系列-LLVM、Clang
    java开发系列-Http协议
    iOS开发系列-SQLite
    iOS逆向系列-theos
    <Java><类加载机制><反射>
    <Java><!!!><面试题>
    <Java><修饰符>
    <Java><类与对象><OOP>
  • 原文地址:https://www.cnblogs.com/heyujun/p/10199794.html
Copyright © 2020-2023  润新知