zoukankan      html  css  js  c++  java
  • [CF1010E]Store[kd-tree]

    题意

    有一个长方体,不知道它的位置,给出 (n) 个一定在长方体内的点和 (m) 个一定不在的点,有 (k) 次询问,每次询问一个点是否 在、不在、不确定 在长方体内。

    (nleq 10^5)

    分析

    • 一道模板题。

    • 发现实际的可行区域并不是一个规则图形,貌似不好维护。

    • 我们考虑每次询问一个点,容易求出满足要求的最小的矩形。此时就变成了一个三维数点问题,离线 (cdq) 分治或者 (kd-tree) 都可以。

    • 总时间复杂度为 (O(nsqrt n))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    #define go(u) for(int i = head[u], v = e[i].to; i; i=e[i].lst, v=e[i].to)
    #define rep(i, a, b) for(int i = a; i <= b; ++i)
    #define pb push_back
    inline int gi() {
        int x = 0,f = 1;
        char ch = getchar();
        while(!isdigit(ch)) {
            if(ch == '-') f = -1;
            ch = getchar();
        }
        while(isdigit(ch)) {
            x = (x << 3) + (x << 1) + ch - 48;
            ch = getchar();
        }
        return x * f;
    }
    template <typename T> inline void Max(T &a, T b){if(a < b) a = b;}
    template <typename T> inline void Min(T &a, T b){if(a > b) a = b;}
    const int N = 1e5 + 7, inf = 0x3f3f3f3f;
    int d[3], lim[3][2];
    int n, m, k, D, rt;
    #define Ls t[o].ch[0]
    #define Rs t[o].ch[1]
    struct node {
    	int ch[2], d[3], l[3], r[3], s;
    	node(){memset(l, 0x3f, sizeof l);}
    	bool operator <(const node &rhs) const {
    		return d[D] < rhs.d[D];
    	}
    }t[N], A, tmp;
    void mt(int o, int s) {
    	rep(i, 0, 2) Min(t[o].l[i], t[s].l[i]), Max(t[o].r[i], t[s].r[i]);
    	t[o].s += t[s].s;
    }
    void build(int d, int l, int r, int &o) {
    	if(l > r) return;
    	D = d; o = l + r >> 1;
    	nth_element(t + l, t + o, t + r + 1);
    	rep(i, 0, 2) t[o].l[i] = t[o].r[i] = t[o].d[i];
    	if(l < o) build((d + 1) % 3, l, o - 1, Ls), mt(o, Ls);
    	if(r > o) build((d + 1) % 3, o + 1, r, Rs), mt(o, Rs);
    }
    bool all(int o) {
    	rep(i, 0, 2) {
    		if(!(lim[i][0] <= t[o].l[i] && t[o].r[i] <= lim[i][1])) return 0;
    	}
    	return 1;
    }
    bool empty(int o) {
    	rep(i, 0, 2) if(t[o].r[i] < lim[i][0] || lim[i][1] < t[o].l[i]) return 1;
    	return 0;
    }
    bool in(int o) {
    	rep(i, 0, 2) {
    		if(!(lim[i][0] <= t[o].d[i] && t[o].d[i] <= lim[i][1])) return 0;
    	}
    	return 1;
    }
    int query(int d, int o) {
    	if(!o) return 0;
    	int s = in(o);
    	if(all(o)) return t[o].s;
    	if(empty(o)) return 0;
    	return query((d + 1) % 3, Ls) + s + query((d + 1) % 3, Rs);
    }
    int main() {
    	rep(i, 0, 2) scanf("%*d");
    	n = gi(), m = gi(), k = gi();
    	rep(i, 1, n) {
    		rep(j, 0, 2) d[j] = gi(), Min(A.l[j], d[j]), Max(A.r[j], d[j]);
    	}
    	rep(i, 1, m) {
    		rep(j, 0, 2) t[i].d[j] = gi();
    		t[i].s = 1;
    		bool fg = 1;
    		rep(j, 0, 2) fg &= A.l[j] <= t[i].d[j] && t[i].d[j] <= A.r[j];
    		if(fg) return puts("INCORRECT"), 0;
    	}
    	build(0, 1, m, rt);
    	puts("CORRECT");
    	rep(i, 1, k) {
    		bool fg = 1;
    		rep(j, 0, 2) {
    			d[j] = gi();
    			lim[j][0] = min(d[j], A.l[j]);
    			lim[j][1] = max(d[j], A.r[j]);
    			fg &= A.l[j] <= d[j] && d[j] <= A.r[j];
    		}
    		if(fg) { puts("OPEN"); continue;}
    		if(query(0, rt)) puts("CLOSED");
    		else puts("UNKNOWN");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Dynamic 365 中创建编码规则
    程序员和产品经理之间的恩怨情仇
    Scrum已经俘获中国开发者的心? ——从《2017年开发者调查报告》看真相!
    不懂营销的产品经理不是好的产品经理
    关于程序猿之间丧心病狂的鄙视链——编辑器篇
    国内五款好用的开源建站系统
    程序员听到bug后的N种反应,太形象了
    功能至上!国内外最实用的协作类软件盘点
    关于程序员之间丧心病狂的鄙视链——编程语言篇
    结对编程体会
  • 原文地址:https://www.cnblogs.com/yqgAKIOI/p/10130497.html
Copyright © 2011-2022 走看看