今天刚看到这个模板我是懵逼的,这个线段树既没有建树,也没有查询,只有一个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的更多相关文章

  1. hdu1542 矩形面积并(线段树+离散化+扫描线)

    题意: 给你n个矩形,输入每个矩形的左上角坐标和右下角坐标. 然后求矩形的总面积.(矩形可能相交). 题解: 前言: 先说说做这道题的感受: 刚看到这道题顿时就懵逼了,几何 烂的渣渣.后来从网上搜题解 ...

  2. POJ1151Atlantis 矩形面积并 扫描线 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ1151 题意概括 给出n个矩形,求他们的面积并. n<=100 题解 数据范围极小. 我们分3种 ...

  3. HDU 1255 覆盖的面积 (扫描线 线段树 离散化 矩形面积并)

    题目链接 题意:中文题意. 分析:纯手敲,与上一道题目很相似,但是刚开始我以为只是把cnt>=0改成cnt>=2就行了,. 但是后来发现当当前加入的线段的范围之前 还有线段的时候就不行了, ...

  4. POJ 1151 Atlantis 矩形面积求交/线段树扫描线

    Atlantis 题目连接 http://poj.org/problem?id=1151 Description here are several ancient Greek texts that c ...

  5. HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板

    好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解.现在来水一水博客,写一下若干年前的题目的题解. Atlantis Time Limit: 2000/1000 MS (Java/Ot ...

  6. 【HDU 1542】Atlantis 矩形面积并(线段树,扫描法)

    [题目] Atlantis Problem Description There are several ancient Greek texts that contain descriptions of ...

  7. luogu P1856 [USACO5.5]矩形周长Picture 扫描线 + 线段树

    Code: #include<bits/stdc++.h> #define maxn 200007 #define inf 100005 using namespace std; void ...

  8. 【BZOJ4418】[Shoi2013]扇形面积并 扫描线+线段树

    [BZOJ4418][Shoi2013]扇形面积并 Description 给定N个同心的扇形,求有多少面积,被至少K个扇形所覆盖. Input 第一行是三个整数n,m,k.n代表同心扇形的个数,m用 ...

  9. BZOJ 1645: [Usaco2007 Open]City Horizon 城市地平线 扫描线 + 线段树 + 离散化

    Code: #include<cstdio> #include<algorithm> #include<string> #define maxn 1030000 # ...

随机推荐

  1. 使用libcurl,根据url下载对应html页面

    1. [图片] Capture.JPG ​2. [代码]GetPageByURL //static member variable definestring GetPageByURL::m_curPa ...

  2. 用python 实现录入学生作业情况的小程序

    写一个录入学生作业情况的一个程序 1.查看学生作业情况 2.录入学生作业情况 3.可以让输入3次,需要为空的情况 homeworks = { ‘张流量’: {‘2018.3.22’:”未交”,’201 ...

  3. Java_图片处理_02_图片处理工具类库

    二.参考文档 1.Java图片处理工具类库

  4. listen 74

    Genes Link Touch and Hearing Sound and touch may seem completely separate, except possibly when play ...

  5. numpy中的tile函数

    tile()函数可以很方便的生成多维数组.它有两个参数,第一个数是原始数组;第二个表示如何来生成,第一个数字表示生成几行,第二个表示每行有多少个原始数组(如果只写一个数字,那么就默认是一行). fro ...

  6. kettle导数到user_用于left join_20160928

    这篇博客主要是给mysql left join做铺垫,需要现在本地数据库创建一个users 数据表 然后去和 test_a03order表  left join 一.首先在local_db数据库先创建 ...

  7. jQuery 验证 Validation

    jQuery Validation 目录 简介: Form validation made easy. Validate a simple comment form with inline rules ...

  8. gitea (git服务器), 修改配置,更换IP地址

    使用的gitea项目管理git 服务器 (可以不用备份项目, 通过直接修改gitea配置, 直接使用) 步骤1 可以直接访问项目, 步骤2 ,如果已有项目IP地址固定为192.168.1.x, 新的I ...

  9. CS231n 2016 通关 第六章 Training NN Part2

    本章节讲解 参数更新 dropout ================================================================================= ...

  10. 关于ajaxfileupload的使用方法以及一些问题

    使用问题: 1.ajax-fileupload.js handleError 异常 由于本来handleError方法是jquery的方法,但jquery到了某个版本这个方法就去掉了没有了 所以最简单 ...