ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

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\n",ans);
    return 0;
}

 

posted on 2016-06-28 09:30  nul  阅读(453)  评论(0编辑  收藏  举报