您的位置:首页 > 其它

计数方法(扫描线):JLOI 2016 圆的异或并

2016-10-27 21:51 281 查看

Description

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

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

Input

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

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

Output

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

Sample Input

2

0 0 1

0 0 2

Sample Output

3
  这道题是模板题,经典题。

1 #include <algorithm>
2 #include <iostream>
3 #include <cstring>
4 #include <cstdio>
5 #include <cmath>
6 #include <set>
7
8 #include <cassert>
9 using namespace std;
10 const int N=200010,M=600010;
11 int n,px
,py
,r
,top,T;
12 long long sqr(long long a){return a*a;}
13 struct Point{
14     int id,x,tp;
15     friend bool operator<(Point x,Point y){
16         double a=py[x.id]+x.tp*sqrt(sqr(r[x.id])-sqr(T-px[x.id]));
17         double b=py[y.id]+y.tp*sqrt(sqr(r[y.id])-sqr(T-px[y.id]));
18         if(a!=b)return a<b;assert(x.id==y.id);return x.tp<y.tp;
19     }
20 }st[M];
21 bool cmp(Point a,Point b){
22     return a.x<b.x;
23 }
24 int res
;
25 set<Point>s;
26 set<Point>::iterator it;
27 long long ans;
28
29
30 int main(){
31     freopen("circle.in","r",stdin);
32     freopen("circle.out","w",stdout);
33     scanf("%d",&n);
34     for(int i=1;i<=n;i++){
35         scanf("%d%d%d",&px[i],&py[i],&r[i]);
36         st[++top]=(Point){i,px[i]-r[i],1};
37         st[++top]=(Point){i,px[i]+r[i],-1};
38     }
39
40     sort(st+1,st+top+1,cmp);
41     for(int i=1;i<=top;i++){
42         Point x=st[i];T=x.x;
43         if(x.tp==1){
44             it=s.upper_bound((Point){x.id,0,1});
45             if(it==s.end())res[x.id]=1;
46             else{
47                 Point y=*it;
48                 if(y.tp==1)res[x.id]=-res[y.id];
49                 else res[x.id]=res[y.id];
50             }
51             s.insert((Point){x.id,0,-1});
52             s.insert((Point){x.id,0,1});
53         }
54         else{
55             s.erase((Point){x.id,0,-1});
56             s.erase((Point){x.id,0,1});
57         }
58     }
59     for(int i=1;i<=n;i++)
60         ans+=res[i]*sqr(r[i]);
61     printf("%lld\n",ans);
62     return 0;
63 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: