• 【LG4631】[APIO2018]Circle selection 选圆圈


    【LG4631】[APIO2018]Circle selection 选圆圈

    题面

    洛谷

    题解

    (kdt)乱搞剪枝。

    维护每个圆在(x、y)轴的坐标范围

    相当于维护一个矩形的坐标范围为([x-r,x+r],[y-r,y+r])

    可以减小搜索范围

    然后再判断一下一个圆是否在当前搜索的矩形内,不在就剪枝

    #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; }
    #define sqr(x) (1ll * (x) * (x)) 
    const int MAX_N = 3e5 + 10;
    struct Point { int x[2], r, id; } p[MAX_N];
    struct Node {
    	int mn[2], mx[2], ls, rs;
    	Point tp; 
    } t[MAX_N];
    int N, WD, rt, ans[MAX_N], rub[MAX_N], cur, top;
    inline bool operator < (const Point &l, const Point &r) { return l.x[WD] < r.x[WD]; }
    inline bool cmp(const Point &l, const Point &r) { return (l.r == r.r) ? (l.id < r.id) : (l.r > r.r); }
    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++) {
    		int r = t[o].tp.r; 
    		t[o].mx[i] = t[o].tp.x[i] + r; t[o].mn[i] = t[o].tp.x[i] - r; 
    		if (ls) chkmax(t[o].mx[i], t[ls].mx[i]), chkmin(t[o].mn[i], t[ls].mn[i]); 
    		if (rs) chkmax(t[o].mx[i], t[rs].mx[i]), chkmin(t[o].mn[i], t[rs].mn[i]); 
    	} 
    }
    int build(int l, int r, int wd) {
    	if (l > r) return 0;
    	int mid = (l + r) >> 1, o = newnode(); 
    	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; 
    }
    bool chk1(int o, Point tmp) { return sqr(tmp.x[0] - t[o].tp.x[0]) + sqr(tmp.x[1] - t[o].tp.x[1]) <= sqr(tmp.r + t[o].tp.r); } 
    bool chk2(int o, Point tmp) {
    	int x0 = tmp.x[0], x1 = tmp.x[1], r = tmp.r; 
    	if (x0 + r < t[o].mn[0]) return 1;
    	if (x0 - r > t[o].mx[0]) return 1; 
    	if (x1 + r < t[o].mn[1]) return 1;
    	if (x1 - r > t[o].mx[1]) return 1;
    	return 0; 
    } 
    void query(int o, Point tmp) { 
    	if (chk2(o, tmp)) return ; 
    	if (!ans[t[o].tp.id] && chk1(o, tmp)) ans[t[o].tp.id] = tmp.id;
    	if (t[o].ls) query(t[o].ls, tmp);
    	if (t[o].rs) query(t[o].rs, tmp); 
    }
    
    int main () {
    	N = gi();
    	for (int i = 1; i <= N; i++) p[i].x[0] = gi(), p[i].x[1] = gi(), p[i].r = gi(), p[i].id = i; 
    	rt = build(1, N, 0); 
    	sort(p + 1, p + N + 1, cmp);
    	for (int i = 1; i <= N; i++) if (!ans[p[i].id]) query(rt, p[i]);
    	for (int i = 1; i <= N; i++) printf("%d ", ans[i]);
    	printf("
    "); 
    	return 0; 
    } 
    
  • 相关阅读:
    微信中一些常用的js事件积累
    css 设置圆角
    移动开发可能用到的css单位
    移动端触摸划屏,实现内容滑动
    postman发送get请求
    Jmeter 快速入门初识线程组
    python基础(一)简单入门
    Jmeter 快速入门简单的http压测
    Mac下Git的基础操作
    接口测试基础
  • 原文地址:https://www.cnblogs.com/heyujun/p/10199845.html
Copyright © 2020-2023  润新知