扫描线的应用。

扫描线就是用数据结构维护一个相对的顺序不变,带修改的东西。

通常只用于一次询问的情况。

抽象的看做一条垂直于x轴直线从左向右扫过去。

这道题目要求求出所有圆的异或并。

所以我们可以求出每一个圆的系数,然后乘上他们的面积。

由于不会出现相交的情况,所以圆弧的相对顺序是不变的。

所以我们用扫描线加入的时候,讨论一下上面的圆弧分别是上下半圆的情况。

然后比较容易的得出结论。

如果是上半圆,这个圆就属于它。

如果是下半弧,那么和它的包含性相同。

接下来找到它的父亲就可以了。

然后用set来维护这条扫描线,比较函数是计算交点的。

然后需要注意一下精度的处理,以及排序的时候第一关键字和第二关键字。

最后计算答案即可。

#include <set>
#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define maxn 200005 ll n,top=0,cal[maxn],T; struct Circle{
ll x,y,r;
Circle (){}
Circle (ll _x,ll _y,ll _r) {x=_x;y=_y;r=_r;}
void read(){scanf("%lld%lld%lld",&x,&y,&r);}
}a[maxn]; struct Events{
ll id,d;
Events(){}
Events(ll _id,ll _d){id=_id;d=_d;}
void print()
{
printf("By Circle %lld Do %lld\n",id,d);
}
}b[maxn<<1]; #define eps 1e-8 int fcmp(double a)
{
return a<-eps?-1:a>eps;
} struct Node{
ll x,y,r,tag,id;
Node () {}
Node (ll _x,ll _y,ll _r,ll _tag,ll _id) {x=_x;y=_y;r=_r;tag=_tag;id=_id;}
void print()
{
printf("At ( %lld, %lld, %lld) Tag %lld\n",x,y,r,tag);
}
bool operator < (const Node & b) const{
double ya,yb;
ya=1.0*r*r-1.0*(T-x)*(T-x);
ya=1.0*y+1.0*tag*sqrt(ya);
yb=1.0*b.r*b.r-1.0*(T-b.x)*(T-b.x);
yb=1.0*b.y+1.0*b.tag*sqrt(yb);
return fcmp(ya-yb)==0?tag<b.tag:fcmp(ya-yb)<0;
}
}; set <Node> s; bool cmpb(Events first,Events second)
{
ll lf=a[first.id].x-a[first.id].r*first.d,ls=a[second.id].x-a[second.id].r*second.d;
return lf==ls?first.d==second.d?a[first.id].y<a[second.id].y:first.d<second.d:lf<ls;
} void Add(int id,int d)
{
Node P;
if (d==1)
{
P=Node(a[id].x,a[id].y,a[id].r,1,id); s.insert(P);
P=Node(a[id].x,a[id].y,a[id].r,-1,id);s.insert(P);
}
else
{
P=Node(a[id].x,a[id].y,a[id].r,1,id); s.erase(P);
P=Node(a[id].x,a[id].y,a[id].r,-1,id);s.erase(P);
}
} ll query(ll x,ll y)
{
T=x;
Node now=Node(x,y,0,1,1);
Node pre=(*(s.upper_bound(now)));
if (pre.tag==1)
return -cal[pre.id];
else
return cal[pre.id];
} int main()
{
scanf("%lld",&n);
F(i,1,n) a[i].read(); a[++n]=Circle(0,0,3e8);
F(i,1,n) b[++top]=Events(i,1),b[++top]=Events(i,-1);
sort(b+1,b+top+1,cmpb);
cal[n]=-1;Add(n,1);
F(i,2,top-1)
{
if (b[i].d==1) cal[b[i].id]=query(a[b[i].id].x-a[b[i].id].r,a[b[i].id].y);
Add(b[i].id,b[i].d);
}
Add(n,-1);
ll ans=0;
F(i,1,n-1) ans+=cal[i]*a[i].r*a[i].r;
printf("%lld\n",ans);
}

BZOJ 4561 [JLoi2016]圆的异或并 ——扫描线的更多相关文章

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

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

  2. bzoj 4561: [JLoi2016]圆的异或并

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

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

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

  4. 【BZOJ】4561: [JLoi2016]圆的异或并

    题解 我们把圆拆成两个圆弧,按照圆弧的左右端点排序来增加和删除 那么我们把圆弧按照纵坐标排序,一定是两两不相交的 我们新加入一个圆的时候,找上圆弧的前驱,如果前驱是一个上圆弧,那么这个上圆弧所在的圆就 ...

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

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

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

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

  7. BZOJ4561 JLoi2016 圆的异或并 【扫描线】【set】*

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

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

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

  9. [JLOI2016]圆的异或并

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

随机推荐

  1. fdisk - Linux分区表操作工具软件

    总览 fdisk [-u]设备名 fdisk -l [-u] [设备名 ...] fdisk -s分区 ... fdisk -v 描述 硬盘可以被分成一个或多个逻辑磁盘,称为 分区. 这些分区信息都存 ...

  2. 《剑指offer》【调整数组顺序使奇数位于偶数前面】(python版)

    题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分 思路: 我认真看了一下,题目应该是要求在原地调整,所以这里不能再 ...

  3. Python实现注册和登录

    一.注册账号需要实现的功能 1.输入:用户名,密码,密码确认 2.限制1:输入的账号和密码不能为空 3.限制2:两次输入密码必须一致 4.限制3:用户名不能重复 5.限制4:错误次数为4次 6.用字典 ...

  4. 阿里云服务器下安装LAMP环境(CentOS Linux 6.3) 安装与配置 php

    下面我们一起为服务器安装 PHP,在使用 yum 安装软件包的时候,yum 会去默认的资源库里查看我们要安装的软件包,然后到指定的服务器上下载并安装. 但是有的时候,我们要安装的软件包并没有包含在默认 ...

  5. ML.NET技术研究系列1-入门篇

    近期团队在研究机器学习,希望通过机器学习实现补丁发布评估,系统异常检测.业务场景归纳一下: 收集整理数据(发布相关的异常日志.告警数据),标识出补丁发布情况(成功.失败) 选择一个机器学习的Model ...

  6. axios使用思路总结

    一.Axios是什么?用来发送请求的对象,类似之前的ajax 二.如何使用? 目前只说get和post的使用方式.一共有两种. 直接使用配置项的方式,发送请求: 2.使用别名来发送请求 参考: htt ...

  7. mysql五:索引原理与慢查询优化

    一 介绍 为何要有索引? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句 ...

  8. 【PHP】详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI、SCRIPT_NAME、PHP_SELF区别

    实例:1.http://localhost/index.php/Home/Home/index.html $_SERVER['QUERY_STRING'] = ""; $_SERV ...

  9. java一些问题的解答

    1.java 枚举类型和数据二进制等问题思考 以下代码的输出结果是什么?为什么会有这样的输出结果? int X=100; int Y=200; System.out.println("X+Y ...

  10. UVA1484 Alice and Bob's Trip (hdu3660)

    一.前言 最开始卡这题是某大佬给出的树DP专题中的一个,据说类似于对抗搜索(这是啥?)的一题 但是在经历了若干艰难困苦之后发现这题在HDU上A不了——(先卡vector的时间,后卡输入的时间,上了输入 ...