zoukankan      html  css  js  c++  java
  • 洛谷P4631/uoj415/loj2586 [APIO2018] Circle selection 选圆圈

    考虑和一个圆有交集的圆,是平面上的一块区域,所以我们考虑用 (KDtree) 维护。

    两个圆相交的条件 (displaystyle (X_i-X_j)^2+(Y_i-Y_j)^2 leqslant (R_i+R_j)^2)

    考虑怎么剪枝,直接维护 (X,Y,R) 的话不好维护。我们知道圆 (i) 和圆 (j) 有交集的话肯定会和框住圆 (j) 的最小的正方形有交集。

    所以我们维护 (KDtree) 一个子树里所有圆对应的正方形 (X,Y) 的最值来剪枝即可。

    (yuan) 里的 (l,r) :对应的正方形的左下角和右上角的坐标。

    (shu) 里的 (l,r) :子树里正方形 (x,y) 坐标的最小值和最大值。

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #define int long long
    #define lson tr[k].ls
    #define rson tr[k].rs
    using namespace std;
    int n, nowk, cnt, root;
    const int N = 300010;
    int s[N], ans[N];
    struct dian {int x, y;};
    struct yuan {int x, y, R, id; dian l, r;} cir[N];
    struct shu {int ls, rs, id; dian l, r;} tr[N];
    int my1(yuan a, yuan b) {return a.R == b.R ? a.id<b.id: a.R>b.R;}
    int my2(int a, int b) {return nowk ? cir[a].x < cir[b].x : cir[a].y < cir[b].y;}
    void pushup(int k)
    {
    	tr[k].l = cir[tr[k].id].l; tr[k].r = cir[tr[k].id].r;
    	if (lson)tr[k].l.x = min(tr[k].l.x, tr[lson].l.x), tr[k].l.y = min(tr[k].l.y, tr[lson].l.y), tr[k].r.x = max(tr[k].r.x, tr[lson].r.x), tr[k].r.y = max(tr[k].r.y, tr[lson].r.y);
    	if (rson)tr[k].l.x = min(tr[k].l.x, tr[rson].l.x), tr[k].l.y = min(tr[k].l.y, tr[rson].l.y), tr[k].r.x = max(tr[k].r.x, tr[rson].r.x), tr[k].r.y = max(tr[k].r.y, tr[rson].r.y);
    }
    void build(int &k, int l, int r, int now)
    {
    	if (l > r)return;
    	int mid = (l + r) >> 1;
    	nowk = now; nth_element(s + l, s + mid, s + r + 1, my2);
    	k = ++cnt; tr[k].id = s[mid];
    	build(lson, l, mid - 1, now ^ 1); build(rson, mid + 1, r, now ^ 1);
    	pushup(k);
    }
    int p2(int x) {return x * x;}
    int jiao(int i, int j) {return p2(cir[i].x - cir[j].x) + p2(cir[i].y - cir[j].y) <= p2(cir[i].R + cir[j].R);}
    void change(int k, int id)
    {
    	if (!k)return;
    	if (cir[id].r.x < tr[k].l.x || tr[k].r.x < cir[id].l.x || cir[id].r.y < tr[k].l.y || tr[k].r.y < cir[id].l.y)return;
    	if (!ans[cir[tr[k].id].id] && jiao(tr[k].id, id))ans[cir[tr[k].id].id] = cir[id].id;
    	if (lson)change(lson, id); if (rson)change(rson, id);
    }
    signed main()
    {
    	cin >> n;
    	for (int i = 1; i <= n; ++i)
    	{
    		scanf("%lld%lld%lld", &cir[i].x, &cir[i].y, &cir[i].R);
    		cir[i].l.x = cir[i].x - cir[i].R; cir[i].l.y = cir[i].y - cir[i].R; cir[i].r.x = cir[i].x + cir[i].R; cir[i].r.y = cir[i].y + cir[i].R;
    		cir[i].id = i; s[i] = i;
    	}
    	sort(cir + 1, cir + 1 + n, my1); build(root, 1, n, 0);
    	for (int i = 1; i <= n; ++i)
    		if (!ans[cir[i].id])change(root, i);
    	for (int i = 1; i <= n; ++i)printf("%lld ", ans[i]);
    	return 0;
    }
    

    然而 (uoj)(loj) 上有 (hack) 数据,我们只要充分发挥人类智慧旋转一下坐标系就行了。记得开 (long space double).代码在这

  • 相关阅读:
    @RequestParam注解使用:Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
    cglib动态代理导致注解丢失问题及如何修改注解允许被继承
    springboot Autowired BeanNotOfRequiredTypeException
    git根据用户过滤提交记录
    不同包下,相同数据结构的两个类进行转换
    How to use Jackson to deserialise an array of objects
    jooq实践
    java如何寻找main函数对应的类
    Python--matplotlib
    Python 和 Scikit-Learn
  • 原文地址:https://www.cnblogs.com/wljss/p/12627526.html
Copyright © 2011-2022 走看看