zoukankan      html  css  js  c++  java
  • bzoj4561: [JLoi2016]圆的异或并

    Description

    在平面直角坐标系中给定N个圆。已知这些圆两两没有交点,即两圆的关系只存在相离和包含。求这些圆的异或面

    积并。异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆内则不考虑。

    Input

     第一行包含一个正整数N,代表圆的个数。接下来N行,每行3个非负整数x,y,r,表示一个圆心在(x,y),半径为r的

    圆。保证|x|,|y|,≤10^8,r>0,N<=200000

    Output

     仅一行一个整数,表示所有圆的异或面积并除以圆周率Pi的结果。

    用平衡树维护扫描线与圆的交点

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<set>
    typedef long long i64;
    const int N=200010;
    int n;
    i64 xs[N],ys[N],rs[N],X;
    inline i64 p2(i64 x){return x*x;}
    inline int _int(){
        int x=0,c=getchar(),f=1;
        while(c>57||c<48){if(c=='-')f=-1;c=getchar();}
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x*f;
    }
    struct pos{
        i64 x,y;
        int sgn,dep;
        i64 r;
        double Y(){
            i64 a=r-p2(x-X);
            if(a<0)return y;
            return y+sgn*sqrt(a);
        }
    };
    bool operator<(pos a,pos b){
        double x=a.Y(),y=b.Y();
        if(fabs(x-y)>=.5)return x<y;
        return a.sgn<b.sgn;
    }
    struct event{
        bool in;
        int id;
        i64 x(){
            if(in)return xs[id]-rs[id];
            else return xs[id]+rs[id];
        }
    }e[N*2];
    bool operator<(event a,event b){
        i64 c=a.x(),d=b.x();
        if(c!=d)return c<d;
        return a.in<b.in;
    }
    std::set<pos>line;
    int deps[N];
    int xp;
    i64 xv[N*2];
    int main(){
        n=_int();
        for(int i=0;i<n;i++){
            xs[i]=_int();ys[i]=_int();rs[i]=_int();
            xv[i*2]=(e[i*2]=(event){1,i}).x();
            xv[i*2+1]=(e[i*2+1]=(event){0,i}).x();
        }
        std::sort(e,e+n*2);
        for(int p=0;p<n*2;++p){
            int id=e[p].id,d;
            if(e[p].in){
                X=e[p].x();
                pos w=(pos){xs[id],ys[id],0,0,p2(rs[id])};
                std::set<pos>::iterator it=line.upper_bound(w);
                if(it!=line.end()){
                    w=*it;
                    d=(w.sgn==1?-w.dep:w.dep);
                }else d=1;
                line.insert((pos){xs[id],ys[id],1,d,p2(rs[id])});
                line.insert((pos){xs[id],ys[id],-1,d,p2(rs[id])});
                deps[id]=d;
            }else{
                X=e[p].x();
                line.erase(line.find((pos){xs[id],ys[id],1,0,p2(rs[id])}));
                line.erase(line.find((pos){xs[id],ys[id],-1,0,p2(rs[id])}));
            }
        }
        i64 ans=0;
        for(int i=0;i<n;i++)ans+=rs[i]*rs[i]*deps[i];
        printf("%lld
    ",ans);
        return 0;
    }
  • 相关阅读:
    跟我一起来学ORACLE开发系列之三sql语法篇 老猫
    浅谈Oracle DBlink搭建 老猫
    一个合格的Oracle DBA的速成法摘录 老猫
    Oracle数据库设计要做到五戒 老猫
    Oracle分析函数参考手册一 老猫
    Oracle10G常用维护语句 老猫
    数据库设计中的敏捷方法 老猫
    oracle数据字典总结 老猫
    DBA 1.0与DBA眼中的DBA 2.0时代 老猫
    海水的绘制 szlongman
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5622304.html
Copyright © 2011-2022 走看看