zoukankan      html  css  js  c++  java
  • 洛谷4631 & UOJ415 & LOJ2586:[APIO2018] Circle selection 选圆圈——题解

    https://www.luogu.com.cn/problem/P4631

    http://uoj.ac/problem/415

    https://loj.ac/problem/2586

    正解貌似是可持久化扫描线……不会告辞。

    KD-TREE把圆存下来,每个点存最大覆盖所有圆的矩形。

    然后按照题意从大到小枚举圆去找它的交,我们把圆视作矩形看看是否和当前查询节点的矩形有交,没有就告辞,有就往下找就好了。

    复杂度玄学,通过旋转坐标系可以过。

    (算了了当年心愿吧)

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long double dl;
    const int K=2;
    const int N=3e5+5;
    const dl eps=1e-7;
    const dl alpha=0.233;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    int D,cnt,tot,num,root,rubbish[N];
    struct Point{
        dl x,y;
        Point(dl x0=0,dl y0=0){x=x0,y=y0;}
    };
    Point Rotate(Point a,dl rad){//逆时针旋转rad 
        return Point(a.x*cos(rad)-a.y*sin(rad),a.x*sin(rad)+a.y*cos(rad));
    }
    inline int epssgn(dl x){
        if(fabs(x)<eps)return 0;
        return x<0?-1:1;
    }
    struct Circle{
        dl d[K],r;int id;
        Circle(){}
        Circle(Point p,dl r_,int id_){
            d[0]=p.x;d[1]=p.y;r=r_;id=id_;
        }
        bool operator <(const Circle &a)const{
            return epssgn(d[D]-a.d[D])<0;
        }
    }a[N];
    struct KDTREE{
        int s[2];
        dl x[2],y[2];
        Circle p;
    }tr[N];
    #define ls tr[o].s[0]
    #define rs tr[o].s[1]
    #define cmax(a,b) (a<b?a=b:a)
    #define cmin(a,b) (a>b?a=b:a)
    inline int newnode(){
        if(!tot)return ++cnt;
        return rubbish[tot--];
    }
    inline void upd(int f,int x){
        cmin(tr[f].x[0],tr[x].x[0]),cmax(tr[f].x[1],tr[x].x[1]);
        cmin(tr[f].y[0],tr[x].y[0]),cmax(tr[f].y[1],tr[x].y[1]);
    }
    inline void pushup(int o){
        tr[o].x[0]=tr[o].p.d[0]-tr[o].p.r;
        tr[o].x[1]=tr[o].p.d[0]+tr[o].p.r;
        tr[o].y[0]=tr[o].p.d[1]-tr[o].p.r;
        tr[o].y[1]=tr[o].p.d[1]+tr[o].p.r;
        if(ls)upd(o,ls);if(rs)upd(o,rs);
    }
    int build(int l,int r,int d){
        D=d;int mid=(l+r)>>1;
        nth_element(a+l,a+mid,a+r+1);
        int o=newnode();
        tr[o].p=a[mid];
        if(l<mid)ls=build(l,mid-1,d^1),upd(o,ls);else ls=0;
        if(mid<r)rs=build(mid+1,r,d^1),upd(o,rs);else rs=0;
        pushup(o);return o;
    }
    inline dl dis(Circle a,Circle b){
        dl x=a.d[0]-b.d[0],y=a.d[1]-b.d[1];
        return x*x+y*y;
    }
    inline bool check(Circle a,Circle b){
        dl R=a.r+b.r;
        return epssgn(dis(a,b)-R*R)<=0;
    }
    inline bool outside(int o,Circle x){
        if(epssgn(x.d[0]-x.r-tr[o].x[1])>0)return 1;
        if(epssgn(x.d[0]+x.r-tr[o].x[0])<0)return 1;
        if(epssgn(x.d[1]-x.r-tr[o].y[1])>0)return 1;
        if(epssgn(x.d[1]+x.r-tr[o].y[0])<0)return 1;
        return 0;
    }
    int ans[N];
    void query(int o,Circle x){
        if(!o)return;
        if(outside(o,x))return;
        if(!ans[tr[o].p.id]&&check(x,tr[o].p))ans[tr[o].p.id]=x.id;
           query(ls,x);query(rs,x);
    }
    bool cmp(Circle a,Circle b){
        return epssgn(a.r-b.r)>0||(epssgn(a.r-b.r)==0&&a.id<b.id);
    }
    int main(){
        int n=read();
        for(int i=1;i<=n;i++){
            dl x=read(),y=read(),r=read();
            a[i]=Circle(Rotate(Point(x,y),alpha),r,i);
        }
        root=build(1,n,0);
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=n;i++)if(!ans[a[i].id])query(root,a[i]);
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
        puts("");
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    python 接口自动化测试--框架定型(六)
    python 接口自动化测试--框架整改(五)
    持续集成接口自动化-jmeter+ant+jenkins(一)
    记 suds 模块循环依赖的坑-RuntimeError: maximum recursion depth exceeded
    python 接口自动化测试(四)
    python 接口自动化测试(三)
    python 接口自动化测试(二)
    python 接口自动化测试(一)
    Jmeter 正则提取器
    python 正则提取(re模块)
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/12419229.html
Copyright © 2011-2022 走看看