矩形面积并-扫描线 线段树 离散化 模板-poj1151 hdu1542
今天刚看到这个模板我是懵逼的,这个线段树既没有建树,也没有查询,只有一个update,而且区间成段更新也没有lazy标记....研究了一下午,我突然我发现我以前根本不懂扫描线,之所以没有lazy标记,是因为扫描线每次只查询1-n里的所有有值的区间长度,因为只要1-n,而不会查找到某些小区间,所以也就不用lazy,而且也无需查询,每次插入完只需要 知道sum[1]是多少即可。所以一个update函数即可。注意的是,线段树的叶子节点不是x轴或者y轴上的点,而是一个个区间,由矩形的长或者宽间距所构成的区间。比如 你现在要更新的这条边的两个端点在x轴上是 x=1,和x=6,更新的l=1,r=5,因为1->6 中间有5个区间 偷别人博客的一张图来看一下就是这样的效果:
所以线段树维护的是 这些小区间
然后剩下的细节就很好懂了
#include<cstdio> #include<string.h> #include<algorithm> #define inf 0x3f3f3f3f const int maxn=; using namespace std; #define lson (id<<1) #define rson ((id<<1)|1) #define mid ((l+r)>>1) double a[maxn+]; double sum[maxn+]; int flag[maxn+]; int n,l,r,k,cnt,icase; double ans; double X1,Y1,X2,Y2; struct node{
double lx,rx,y;
int f;
node(){};
node(double lx_,double rx_,double y_,int f_){
lx=lx_,rx=rx_,y=y_,f=f_;
}
}line[maxn+]; int cmp(node a,node b){
return a.y<b.y;
} int bin_search(double val){
int lb=,ub=k;
int Mid=(lb+ub)>>;
while(ub-lb>){
Mid=(ub+lb)>>;
if(a[Mid]==val) return Mid;
else if(a[Mid]>val) ub=Mid;
else if(a[Mid]<val) lb=Mid;
}
if(a[Mid]==val) return Mid;
if(a[ub]==val) return ub;
if(a[lb]==val) return lb;
} void push_up(int id,int l,int r){
if(flag[id]) sum[id]=a[r+]-a[l];
else if(l==r) sum[id]=;
else sum[id]=sum[lson]+sum[rson];
} void update(int id,int l,int r,int ql,int qr,int val){
if(ql<=l&&r<=qr){
flag[id]+=val;
push_up(id,l,r);
return ;
}
if(ql<=mid){
update(lson,l,mid,ql,qr,val);
}
if(qr>=mid+){
update(rson,mid+,r,ql,qr,val);
}
if(qr<=mid){
update(lson,l,mid,ql,qr,val);
} else if(ql>=mid+){
update(rson,mid+,r,ql,qr,val);
} else {
update(lson,l,mid,ql,mid,val);
update(rson,mid+,r,mid+,qr,val);
}
push_up(id,l,r);
} void init(){
k=;
cnt=;
ans=;
memset(flag,,sizeof(flag));
memset(sum,,sizeof(sum));
} void solve(){
for(int i=;i<=n;i++){
scanf("%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2);
line[++cnt]=node(X1,X2,Y1,);
a[cnt]=X1;
line[++cnt]=node(X1,X2,Y2,-);
a[cnt]=X2;
}
sort(a+,a++cnt);
sort(line+,line++cnt,cmp);
k=;
for(int i=;i<=cnt;i++){
if(a[i]!=a[i+]){
a[++k]=a[i];
}
}
for(int i=;i<cnt;i++){
l=bin_search(line[i].lx);
r=bin_search(line[i].rx)-;
update(,,k,l,r,line[i].f);
ans+=sum[]*(line[i+].y-line[i].y);
}
printf("Test case #%d\n",++icase);
printf("Total explored area: %.2f\n\n",ans);
} int main()
{
while(scanf("%d",&n)!=EOF&&n){
init();
solve();
}
return ;
}
矩形面积并-扫描线 线段树 离散化 模板-poj1151 hdu1542的更多相关文章
- hdu1542 矩形面积并(线段树+离散化+扫描线)
题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...
- POJ1151Atlantis 矩形面积并 扫描线 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ1151 题意概括 给出n个矩形,求他们的面积并. n<=100 题解 数据范围极小. 我们分3种 ...
- HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)
题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了, ...
- POJ 1151 Atlantis 矩形面积求交/线段树扫描线
Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...
- HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板
好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...
- 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)
[题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...
- luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树
Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...
- 【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树
[BZOJ4418][Shoi2013]扇形面积并 Description 给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖. Input 第一行是三个整数n,m,k.n代表同心扇形的个数,m用 ...
- BZOJ 1645: [Usaco2007 Open]City Horizon 城市地平线 扫描线 + 线段树 + 离散化
Code: #include<cstdio> #include<algorithm> #include<string> #define maxn 1030000 # ...
随机推荐
- 分享知识-快乐自己:SpringMvc中 页面日期格式到后台的类型转换
日期格式的类型转换: 以往在 from 表单提交的时候,都会有字符串.数字.还有时间格式等信息. 往往如果是数字提交的话底层会自动帮我们把类型进行了隐式转换. 但是日期格式的却不能自动转换,这就需要我 ...
- 基于深度学习的安卓恶意应用检测----------android manfest.xml + run time opcode, use 深度置信网络(DBN)
基于深度学习的安卓恶意应用检测 from:http://www.xml-data.org/JSJYY/2017-6-1650.htm 苏志达, 祝跃飞, 刘龙 摘要: 针对传统安卓恶意程序检测 ...
- 动态创建TeeChart的简便方法
最近在项目中使用Teechart ocx版本替换了labview的老版本控件,显示效果和效率均有提高,但是却遇到多线程下报access violation的问题. 翻遍大小论坛,最后在官网论坛找到相同 ...
- 关系逻辑运算符---------&&和||
1.&&符号 常规用法没什么好说的,我们来说说其不同于java的特殊之处 (1)&&符号究竟返回什么 我们知道,0,null,defined,null,NaN等都可以转 ...
- Laravel的三种安装方法总结
Laravel号称巨匠级PHP框架,越来越多的PHPer选择它作为开发框架,作为一个Laravel初学者相信很多人向我一样被安装挡在了门外.所以今天结合文档和自己的学习经历总结一下Laravel的安装 ...
- POJ1195Mobile phones (从二维树状数组到cdq分治)
Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows ...
- 主备角色switch
理论知识:Switchover 切换允许primary 和一个备库进行切换,并且这种切换没有数据丢失. 前提条件: 1) 主备库相关参数 fal_client.fal_server .standby_ ...
- BZOJ1878:[SDOI2009]HH的项链
浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 题目传送门:https://www.lydsy.com/JudgeOnline/prob ...
- 洛谷P1018乘积最大——区间DP
题目:https://www.luogu.org/problemnew/show/P1018 区间DP+高精,注意初始化和转移的细节. 代码如下: #include<iostream> # ...
- DBS:目录
ylbtech-DBS:目录 1.返回顶部 1. 2. 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 7.返回顶部 8.返回顶部 9.返回顶 ...