矩形面积并-扫描线 线段树 离散化 模板-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 # ...
随机推荐
- js/html/css做一个简单的图片自动(auto)轮播效果//带注释
FF(firefox)/chrom/ie稳定暂无bug...注意:请自己建立一个images文件,放入几张900*238的图片(注意图片格式和名字与程序中一致). 1. [图片] 1.JPG 2. [ ...
- openfire插件开发环境
创建java工程 SamplePlugin: package com.hoo.server.plugin; import java.io.File; import org.jivesoftware.o ...
- Css公共文件结构
一般一个网站会有这么三个样式: global.css | reset.css(格式化样式) common.css(公共组件样式) layout.css(当前页面样式) 清除全站所有页面的浏览器默认样式 ...
- Dom vs Canvas (译)
原文:dom_vs_canvas 在web上做动画我们有很多选择:svg,dom,canvas,flash等等.但是根据业务场景我们一定能找到最优的技术解决方案,但是何时选择dom,何时使用canva ...
- 【C】字符串常量和字符数组
此次博客是转载某位博主的文章,不过现在找不到了,所以先声明一下. 先贴一段代码: #include <stdio.h> int main(int argc, const char** ar ...
- final修饰变量
final修饰基本类型变量 当使用final修饰基本类型变量时,不能对基本类型变量重新赋值,因此基本类型变量不能被改变 final修饰引用类型变量 当使用final修饰引用类型变量时,它保存的仅仅是一 ...
- yii使用CFrom调用ajax失败的记录
在学习配置yii的CFrom的时候,发现怎么也不能让ajax生效,后来看文档后 ,终于发现了问题的所在. 问题配置文件如下 public function getUserConfig(){ retur ...
- 后缀数组dc3算法模版(待补)
模版: ; #define F(x) ((x)/3+((x)%3==1?0:tb)) #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2) int wa[maxn ...
- iwork 文件格式分析
根据维基百科,到2015年苹果推出的iwork版本 第一章:iwork2008介绍 1.文档结构: 是一个资源合集:压缩格式的(内含文件夹和文件) 在windows下修改iwork的文件后缀为.rar ...
- 世界虽大,但没有破不了的wifi
附加知识: 无线网卡的几种常见工作模式(mode)有: master managed monitor ad-hoc ... 1. [master] 这种模式是常见的AP模式,无线模块本身作为wifi ...