POJ1151 Atlantis 线段树扫描线
扫描线终于看懂了。。。咕咕了快三个月$qwq$
对于所有的横线按纵坐标排序,矩阵靠下的线权值设为$1$,靠上的线权值设为$-1$,然后执行线段树区间加减,每次的贡献就是有效宽度乘上两次计算时的纵坐标之差。
$cnt$数组记录每个位置被覆盖的次数,$sum$数组用来记区间总长度(即有效宽度),所以每一次把$sum[1]$乘上高就行了。
注意到每个$r$都减了$1$,原因是原先的坐标是点的坐标,而现在一个位置代表一个区间。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<vector>
#include<queue>
#include<map>
#include<set>
#define ls (tr<<1)
#define rs (tr<<1|1)
#define ull unsigned long long
#define ll long long
#define R register int
using namespace std;
namespace Fread {
static char B[<<],*S=B,*D=B;
#define getchar() (S==D&&(D=(S=B)+fread(B,1,1<<15,stdin),S==D)?EOF:*S++)
inline int g() {
R ret=,fix=; register char ch; while(!isdigit(ch=getchar())) fix=ch=='-'?-:fix;
do ret=ret*+(ch^); while(isdigit(ch=getchar())); return ret*fix;
} inline bool isempty(const char& ch) {return ch<=||ch>=;}
inline void gs(char* s) {register char ch; while(isempty(ch=getchar())); do *s++=ch; while(!isempty(ch=getchar()));}
}using Fread::g; using Fread::gs;
const int N=;
struct ln {
double l,r,x; int w; ln() {}
ln(double Ll,double rr,double xx,int ww) {l=Ll,r=rr,x=xx,w=ww;}
bool operator < (const ln& that) const {return x<that.x;}
}L[N]; int n,t,tot; double d[N];
int cnt[N<<]; double sum[N<<];
inline void upd(int tr,int l,int r) {
if(cnt[tr]) sum[tr]=d[r+]-d[l];
else if(l==r) sum[tr]=;
else sum[tr]=sum[ls]+sum[rs];
}
inline void change(int tr,int l,int r,int LL,int RR,int vl) {
if(LL<=l&&r<=RR) {cnt[tr]+=vl; upd(tr,l,r); return ;} R md=l+r>>;
if(LL<=md) change(ls,l,md,LL,RR,vl); if(RR>md) change(rs,md+,r,LL,RR,vl); upd(tr,l,r);
}
signed main() {
#ifdef JACK
freopen("NOIPAK++.in","r",stdin);
#endif
while(scanf("%d",&n),n!=) { memset(cnt,,sizeof(cnt)),memset(sum,,sizeof(sum)); tot=;
for(R i=;i<=n;++i) { register double l,p,r,b;
scanf("%lf%lf%lf%lf",&l,&p,&r,&b);
d[++tot]=l,L[tot]=ln(l,r,p,);
d[++tot]=r,L[tot]=ln(l,r,b,-);
} sort(d+,d+tot+),sort(L+,L+tot+);
n=unique(d+,d+tot+)-d-; register double ans=;
for(R i=;i<=tot;++i) {
R l=lower_bound(d+,d+n+,L[i].l)-d;
R r=lower_bound(d+,d+n+,L[i].r)-d-;
change(,,n,l,r,L[i].w);
ans+=sum[]*(L[i+].x-L[i].x);
} printf("Test case #%d\nTotal explored area: %.2lf\n\n",++t,ans);
}
}
2019.06.13
POJ1151 Atlantis 线段树扫描线的更多相关文章
- hdu1542 Atlantis 线段树--扫描线求面积并
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...
- HDU 1542 - Atlantis - [线段树+扫描线]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...
- HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- 【42.49%】【hdu 1542】Atlantis(线段树扫描线简析)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s) ...
- POJ 1151 - Atlantis 线段树+扫描线..
离散化: 将所有的x轴坐标存在一个数组里..排序.当进入一条线段时..通过二分的方式确定其左右点对应的离散值... 扫描线..可以看成一根平行于x轴的直线..至y=0开始往上扫..直到扫出最后一条平行 ...
- POJ 1151:Atlantis 线段树+扫描线
Atlantis Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 19374 Accepted: 7358 Descrip ...
- hdu 1542 Atlantis (线段树扫描线)
大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...
- hdu 1542&&poj 1151 Atlantis[线段树+扫描线求矩形面积的并]
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- Atlantis poj1151 线段树扫描线
Atlantis poj1151 线段树扫描线 题意 题目给了n个矩形,每个矩形给了左下角和右上角的坐标,矩形可能会重叠,求的是矩形最后的面积. 题解思路 这个是我线段树扫描线的第一题,听了学长的讲解 ...
随机推荐
- Code Chef - Chef and Graph Queries
传送门 题目大意 给定一个$n$个点$m$条边的无向图$(n,m\leq 200000)$. 有$q$每次询问$(q\leq 200000)$,每次给定一个区间$L,R$,求仅保留编号$\in[L,R ...
- Qt Quick之Canvas
QML中的Canvas,俗称画布,它用来定义一个绘图区域,可以使用ECMAScript代码来绘制直线,矩形,贝塞尔曲线,弧线,图片,文字等图元,还可以为这些图元应用填充颜色和边框颜色,甚至还可以进行低 ...
- 用遗传算法解决TSP问题
浅谈遗传算法:https://www.cnblogs.com/AKMer/p/9479890.html Description \(小m\)在踏上寻找\(小o\)的路程之后不小心碰到了大魔王\(fat ...
- 排成一行的li之间的间隙问题
现象 对于ul下li排成一行的布局(即li的display由list-item设为inline-block): 情况1 如果这些li在书写的时候有换行或者有空格,且ul本身的font-size不为0, ...
- 【转】 Pro Android学习笔记(六四):安全和权限(1):签发apk
目录(?)[-] Android安全模型 数字证书签发 Debug的keystore 生产unsigned的apk 为apk进行证书签发 align安装包 使用Export Wizard生成签发的ap ...
- 【转】 Pro Android学习笔记(四三):Fragment(8):再谈Transaction和管理器
目录(?)[-] Transaction的一些操作 再谈FragmentManager 调用其他fragment的方法 唤起activity 唤起fragment和相互通信 一些其它 Transact ...
- ss1
首先,对系统来一次升级,以解决一些莫名其妙的依赖问题. sudo yum update 然后安装Python-pip. sudo yum -y install python-pip 注意,通过yum包 ...
- oracle上课 学习2 oracle 游标 存储过程 有用
1.1. 训练描述 使用游标,打印emp中20号部门的所有员工的信息 操作步骤答案 declare cursor c_emp is select * from emp where deptno=10 ...
- 项目一:第六天 WebService写接口 和CXF框架
1 课程计划 1. webService入门(了解) 2. 基于jdk1.7开发webservice服务(了解) 3. Apache CXF框架入门(掌握) 4. 基于CXF框架搭建CRM系统(掌握) ...
- Linux系统挂载FAT32的U盘
1:将U盘插入USB接口,检查是否插好 2:用fdisk命令检查分区和USB设备信息 [root@yhwang ~]# fdisk -l Disk /dev/sda: 1000.2 GB, 10002 ...