BZOJ 4561 [JLoi2016]圆的异或并 ——扫描线
扫描线的应用。
扫描线就是用数据结构维护一个相对的顺序不变,带修改的东西。
通常只用于一次询问的情况。
抽象的看做一条垂直于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]圆的异或并 ——扫描线的更多相关文章
- BZOJ 4561: [JLoi2016]圆的异或并 扫描线 + set
看题解看了半天...... Code: #include<bits/stdc++.h> #define maxn 200010 #define ll long long using nam ...
- bzoj 4561: [JLoi2016]圆的异或并
Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面 积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个 ...
- 【BZOJ4561】[JLoi2016]圆的异或并 扫描线
[BZOJ4561][JLoi2016]圆的异或并 Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面积并.异或面积并为:当一 ...
- 【BZOJ】4561: [JLoi2016]圆的异或并
题解 我们把圆拆成两个圆弧,按照圆弧的左右端点排序来增加和删除 那么我们把圆弧按照纵坐标排序,一定是两两不相交的 我们新加入一个圆的时候,找上圆弧的前驱,如果前驱是一个上圆弧,那么这个上圆弧所在的圆就 ...
- [BZOJ4561][JLOI2016]圆的异或并(扫描线)
考虑任何一条垂直于x轴的直线,由于圆不交,所以这条直线上的圆弧构成形似括号序列的样子,且直线移动时圆之间的相对位置不变. 将每个圆拆成两边,左端加右端删.每次加圆时考虑它外面最内层的括号属于谁.用se ...
- bzoj4561: [JLoi2016]圆的异或并 圆的扫描线
地址:http://www.lydsy.com/JudgeOnline/problem.php?id=4561 题目: 4561: [JLoi2016]圆的异或并 Time Limit: 30 Sec ...
- BZOJ4561 JLoi2016 圆的异或并 【扫描线】【set】*
BZOJ4561 JLoi2016 圆的异或并 Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面积并.异或面积并为:当一片区 ...
- bzoj4561: [JLoi2016]圆的异或并
Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面 积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个 ...
- [JLOI2016]圆的异或并
Description 在平面直角坐标系中给定N个圆.已知这些圆两两没有交点,即两圆的关系只存在相离和包含.求这些圆的异或面积并.异或面积并为:当一片区域在奇数个圆内则计算其面积,当一片区域在偶数个圆 ...
随机推荐
- python_48_Python3中字符编码与转码
python3默认是Unicode,不用声明# -*- coding:utf-8 -*-,如果声明则是utf-8 unicode='你好' print('utf-8:',unicode.encode( ...
- 【luogu P3608 [USACO17JAN]Balanced Photo平衡的照片】 题解
题目链接:https://www.luogu.org/problemnew/show/P3608 乍一看很容易想到O(N^2)的暴力. 对于每个H[i]从i~i-1找L[i]再从i+1~n找R[i], ...
- 牛客小白月赛5 D 阶乘(factorial) 【前缀】
链接:https://www.nowcoder.com/acm/contest/135/D 题目描述 输入描述: 输入数据共一行,一个正整数n,意义如“问题描述”. 输出描述: 输出一行描述答案: 一 ...
- 六、MySQL 删除数据库
MySQL 删除数据库 使用普通用户登陆 MySQL 服务器,你可能需要特定的权限来创建或者删除 MySQL 数据库,所以我们这边使用 root 用户登录,root 用户拥有最高权限. 在删除数据库过 ...
- PHP namespace、abstract、interface、trait使用介绍
小菜鸟一枚,一直搞不懂 namespace.abstract.interface.trait 这些关系,就抽出几天时间研究,做个总结,不足之处希望大家指正交流. namespace 命名空间 介绍:顾 ...
- 【PHP】什么时候使用Try Catch(转)
几条建议: 如果无法处理某个异常,那就不要捕获它. 如果捕获了一个异常,请不要胡乱处理它. 尽量在靠近异常被抛出的地方捕获异常. 在捕获异常的地方将它记录到日志中,除非您打算将它重新抛出. 按 ...
- Fakeapp 入门教程(3):参数篇
参数可以让软件自由度更高.Fakeapp的参数并不算多,但是也非常使用.本文就讲解下几个重要的参数.参数设置界面可以通过点击SETTINGS打开. 参数修改无需点击保存,一旦修改直接生效. Proce ...
- 06.VUE学习之非常实用的计算属性computed实例
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...
- linux Ubuntu18.04 安装配置MySQL
1.安装 ubuntu上安装mysql非常简单只需要几条命令就可以完成. 1. sudo apt-get install mysql-server 2. apt-get install mysql ...
- django_mysql_配置
配置 1. 安装Pymysql pip install PyMySQL 然后在项目同名_init__添加 from pymysql import install_as_MySQLdb install_ ...