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


    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[N],py[N],r[N],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[N];
    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
    ",ans);    
    62     return 0;
    63 }
  • 相关阅读:
    Flask--目录
    Linux相关目录
    Mac 提示错误”xcrun: error“
    subprocess模块
    压缩模块
    GitPython模块
    Ansible-ansible命令
    YAML语法
    Ansible-安装
    Ansible-概念
  • 原文地址:https://www.cnblogs.com/TenderRun/p/6005762.html
Copyright © 2020-2023  润新知