zoukankan      html  css  js  c++  java
  • [APIO2018] Circle selection 选圆圈

    Description

    给出 (n) 个圆 ((x_i,y_i,r_i))
    每次重复以下步骤:
    找出半径最大的圆,并删除与这个圆相交的圆
    求出每一个圆是被哪个圆删除的

    Solution

    (kd-tree) 搞一下
    维护能够围住所有圆的最小矩形
    然后模拟题意,枚举半径最大的圆
    查询时就判断询问的圆是否与这个矩形有交,有交就递归下去

    #include<bits/stdc++.h>
    #define sqr(x) ((x)*(x))
    using namespace std;
    template<class T>void gi(T &x){
    	int f;char c;
    	for(f=1,c=getchar();c<'0'||c>'9';c=getchar())if(c=='-')f=-1;
    	for(x=0;c<='9'&&c>='0';c=getchar())x=x*10+(c&15);x*=f;
    }
    const int N=3e5+10,inf=2e9+10;const double eps=1e-7;
    int n,rt,D,ans[N];
    struct data{
    	double a[2],mn[2],mx[2],R;int l,r,tag,id;
    	inline double& operator [](int x){return a[x];}
    }t[N],c[N],W;
    inline bool operator <(data p,data q){return p[D]<q[D];}
    inline bool comp(data p,data q){return p.R!=q.R?p.R>q.R:p.id<q.id;}
    inline void upd(int o){
    	int l=t[o].l,r=t[o].r;
    	for(int i=0;i<2;i++){
    		t[o].mx[i]=-inf;t[o].mn[i]=inf;
    		if(!t[o].tag)t[o].mn[i]=min(t[o].mn[i],t[o].a[i]-t[o].R),
    							t[o].mx[i]=max(t[o].mx[i],t[o].a[i]+t[o].R);
    		if(l)t[o].mn[i]=min(t[o].mn[i],t[l].mn[i]),
    				  t[o].mx[i]=max(t[o].mx[i],t[l].mx[i]);
    		if(r)t[o].mn[i]=min(t[o].mn[i],t[r].mn[i]),
    				  t[o].mx[i]=max(t[o].mx[i],t[r].mx[i]);
    	}
    }
    inline int build(int l,int r,int k){
    	int mid=(l+r)>>1,o=mid;D=k;
    	nth_element(t+l,t+mid,t+r+1);
    	if(l<mid)t[o].l=build(l,mid-1,k^1);
    	if(r>mid)t[o].r=build(mid+1,r,k^1);
    	return upd(o),o;
    }
    inline void query(int o){
    	if(!o)return ;
    	for(int i=0;i<2;i++)
    		if(W.a[i]-W.R>t[o].mx[i] || W.a[i]+W.R<t[o].mn[i])return ;
    	if(!t[o].tag){
    		double dis=0,R=sqr(W.R+t[o].R);
    		for(int i=0;i<2;i++)dis+=sqr(t[o].a[i]-W.a[i]);
    		if(dis-R<eps)ans[t[o].id]=W.id,t[o].tag=1;
    	}
    	query(t[o].l);query(t[o].r);
    }
    int main(){
    	freopen("pp.in","r",stdin);
    	freopen("pp.out","w",stdout);
    	cin>>n;
    	double x,y,z;
    	for(int i=1;i<=n;i++){
    		gi(x);gi(y);gi(z);
    		t[i].a[0]=c[i].a[0]=x;t[i].a[1]=c[i].a[1]=y;
    		t[i].R=c[i].R=z;c[i].id=t[i].id=i;
    	}
    	rt=build(1,n,0);
    	sort(c+1,c+n+1,comp);
    	for(int i=1;i<=n;i++){
    		if(ans[c[i].id])continue;
    		W=c[i];
    		query(rt);
    	}
    	for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    	return 0;
    }
    
    
  • 相关阅读:
    jQuery EasyUI API 中文文档 数字框(NumberBox)
    jQuery EasyUI API 中文文档 数值微调器(NumberSpinner)
    jQuery EasyUI API 中文文档 日期时间框(DateTimeBox)
    jQuery EasyUI API 中文文档 微调器(Spinner)
    jQuery EasyUI API 中文文档 树表格(TreeGrid)
    jQuery EasyUI API 中文文档 树(Tree)
    jQuery EasyUI API 中文文档 属性表格(PropertyGrid)
    EntityFramework 数据操作
    jQuery EasyUI API 中文文档 对话框(Dialog)
    jQuery EasyUI API 中文文档 组合表格(ComboGrid)
  • 原文地址:https://www.cnblogs.com/Yuzao/p/9100436.html
Copyright © 2011-2022 走看看