BZOJ4561 JLoi2016 圆的异或并


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


还是挺好的一道题吧,但是考场上没有做出来啊

什么鬼畜扫描线


首先我们发现如果考虑一下容斥,嵌套起来的圆是加减加减这样的

也就是说一个圆的面积应该加上还是减去只和包住它且最小的圆有关系

然后我们考虑一个圆最左边的一个节点(x,y)" role="presentation" style="position: relative;">(x,y)(x,y),如果另一个圆包含了这个圆那么在最左边的时候一定存在(x,y1)" role="presentation" style="position: relative;">(x,y1)(x,y1)和(x,y2)" role="presentation" style="position: relative;">(x,y2)(x,y2)满足y1&lt;y&lt;y2" role="presentation" style="position: relative;">y1<y<y2y1<y<y2

然后如果两个圆的关系是相离,一定存在(x,y1)" role="presentation" style="position: relative;">(x,y1)(x,y1)和(x,y2)" role="presentation" style="position: relative;">(x,y2)(x,y2)满足y1&lt;=y2&lt;y" role="presentation" style="position: relative;">y1<=y2<yy1<=y2<y或者y&lt;y1&lt;=y2" role="presentation" style="position: relative;">y<y1<=y2y<y1<=y2

然后我们只需要用一种支持查询前驱后继的数据结构来维护到一个圆的起始位置的时候恰好比它y大的那个圆是什么,用括号序列的形式来理解一下,如果方向相同就是包含,否则就是相离

然后扫描线扫过去


#include<bits/stdc++.h>
using namespace std;
#define N 200010
#define INF 0x3f3f3f3f
#define pi pair<int,int>
struct Circle{int x,y,r;}c[N];
struct Node{int x,id,typ;}p[N<<1];
struct Point{int id,typ;};
long long pow2(int x){return 1ll*x*x;}
int nowx;
bool operator < (const Point &x,const Point &y){
double yx=(double)c[x.id].y+(double)x.typ*(double)sqrt(pow2(c[x.id].r)-pow2(c[x.id].x-nowx));
double yy=(double)c[y.id].y+(double)y.typ*(double)sqrt(pow2(c[y.id].r)-pow2(c[y.id].x-nowx));
if(yx==yy)return x.typ<y.typ;
return yx<yy;
}
bool cmp(Node a,Node b){return a.x<b.x;}
int n,tot=0,vis[N];
set<Point> s;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&c[i].x,&c[i].y,&c[i].r);
p[++tot]=(Node){c[i].x-c[i].r,i,1};
p[++tot]=(Node){c[i].x+c[i].r,i,-1};
}
sort(p+1,p+tot+1,cmp);
for(int i=1;i<=tot;i++){
nowx=p[i].x;
if(p[i].typ==1){
set<Point>::iterator it;
it=s.upper_bound((Point){p[i].id,1});
if(it==s.end())vis[p[i].id]=1;
else{
if(it->typ==1)vis[p[i].id]=-vis[it->id];
else vis[p[i].id]=vis[it->id];
}
s.insert((Point){p[i].id,1});
s.insert((Point){p[i].id,-1});
}else{
s.erase((Point){p[i].id,1});
s.erase((Point){p[i].id,-1});
}
}
long long ans=0;
for(int i=1;i<=n;i++)ans+=pow2(c[i].r)*vis[i];
printf("%lld",ans);
return 0;
}

BZOJ4561 JLoi2016 圆的异或并 【扫描线】【set】*的更多相关文章

  1. [BZOJ4561][JLOI2016]圆的异或并(扫描线)

    考虑任何一条垂直于x轴的直线,由于圆不交,所以这条直线上的圆弧构成形似括号序列的样子,且直线移动时圆之间的相对位置不变. 将每个圆拆成两边,左端加右端删.每次加圆时考虑它外面最内层的括号属于谁.用se ...

  2. 【BZOJ4561】[JLoi2016]圆的异或并 扫描线

    [BZOJ4561][JLoi2016]圆的异或并 Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面积并.异或面积并为:当一 ...

  3. bzoj4561: [JLoi2016]圆的异或并 圆的扫描线

    地址:http://www.lydsy.com/JudgeOnline/problem.php?id=4561 题目: 4561: [JLoi2016]圆的异或并 Time Limit: 30 Sec ...

  4. bzoj4561: [JLoi2016]圆的异或并

    Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面 积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个 ...

  5. BZOJ 4561 [JLoi2016]圆的异或并 ——扫描线

    扫描线的应用. 扫描线就是用数据结构维护一个相对的顺序不变,带修改的东西. 通常只用于一次询问的情况. 抽象的看做一条垂直于x轴直线从左向右扫过去. 这道题目要求求出所有圆的异或并. 所以我们可以求出 ...

  6. BZOJ4561 JLOI2016圆的异或并(扫描线+平衡树)

    考虑一条扫描线从左到右扫过这些圆.观察某一时刻直线与这些圆的交点,可以发现构成一个类似括号序列的东西,括号的包含关系与圆的包含关系是相同的.并且当扫描线逐渐移动时,括号间的相对顺序不变.于是考虑用se ...

  7. BZOJ4561: [JLoi2016]圆的异或并 计算几何+treap

    因为本题保证两圆之间只有相包含或相离(不用担心两圆重合 因为我没有RE) 所以每个圆之间的相对位置是确定的  也就是可以按极角排序的, 所以可以按横坐标排序后 扫描同时用treap维护加圆删圆(即遇到 ...

  8. BZOJ 4561: [JLoi2016]圆的异或并 扫描线 + set

    看题解看了半天...... Code: #include<bits/stdc++.h> #define maxn 200010 #define ll long long using nam ...

  9. 【BZOJ-4561】圆的异或并 set + 扫描线

    4561: [JLoi2016]圆的异或并 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 254  Solved: 118[Submit][Statu ...

随机推荐

  1. Java管理扩展指南之JMX技术总览

    JMX(Java管理扩展)系列 JMX(Java管理扩展)系列旨在介绍包含于Java基础版本(Java SE)中的JMX技术.本系列提供了如何使用JMX重要技术特性的诸多示例. 一.JMX技术总览简要 ...

  2. pwm计时器

    1 PWM timer定时器与(watchdog差不多)2 5个16位的定时器,独立的,其中,NO PIN 没有输出.16表示ffff,和ADC中10表示3FF一样.而寄存器都是32位.(以后6410 ...

  3. char数组

    *****************************************************************char 类型的数组(c语言中是没有字符串的)char name[20 ...

  4. printf %m

    最近看别人的项目发现有 printf("%m") 这种写法,这是什么输出格式呢? 通过 man 查找得知: m (Glibc extension.) Print output of ...

  5. ASP.NET网站使用Kindeditor富文本编辑器配置步骤

    1. 下载编辑器 下载 KindEditor 最新版本,下载页面: http://www.kindsoft.net/down.php 2. 部署编辑器 解压 kindeditor-x.x.x.zip ...

  6. COW写时复制

    body, table{font-family: 微软雅黑; font-size: 10pt} table{border-collapse: collapse; border: solid gray; ...

  7. 在Linux下设置定时任务(每分钟执行一次特定的shell脚本)

    在当前用户下,开始编辑定时任务 crontab -e 按键 i 进入编辑模式 输入下述命令 */ * * * * sh /***/*****.sh 然后按键 Esc 退出编辑模式,再输入 wq 保存退 ...

  8. 左边的div导航根据右部div内容的高自动调整

    div结构如下: <div class="mainbody"> <div class="left">导航</div> < ...

  9. etl工具-Bireme

    前段时间做数据仓库项目,自己实现了一部分etl功能,后面一直没有时间去深入挖掘.这个工具貌似不错,写个帖子做下记录: https://hashdatainc.github.io/bireme/READ ...

  10. Linux:col命令详解

    col 经常用于将说明文件转存为纯文本以方便阅读 语法 col(选项) 选项 -b:过滤掉所有的控制字符,包括RLF和HRLF: -f:滤掉RLF字符,但允许将HRLF字符呈现出来: -x:以多个空格 ...