将 x 轴上的点进行离散化,扫描线沿着 y 轴向上扫描

每次添加一条边不断找到当前状态有效边的长度 , 根据这个长度和下一条边形成的高度差得到一块合法的矩形的面积

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm> using namespace std; const int MAX=+;
int flag[MAX<<];//记录某个区间的下底边个数
double sum[MAX<<];//记录某个区间的下底边总长度
double x[MAX];//对x进行离散化,否则x为浮点数且很大无法进行线段树 struct Seg{//线段
double x1,x2,y;
int d;
Seg(){}
Seg(double x1 , double x2 , double y , int d):x1(x1),x2(x2),y(y),d(d){}
bool operator<(const Seg &a)const{
return y<a.y;
}
}s[MAX]; void updateCur(int n,int left,int right){
if(flag[n]) sum[n] = x[right+] - x[left];//表示该区间整个线段长度可以作为底边
else if(left == right) sum[n] = ;//叶子结点则底边长度为0(区间内线段长度为0)
else sum[n] = sum[n<<] + sum[n<<|];
} void update(int o , int l , int r , int s , int t , int d){
if(s<=l && r<=t){//该区间是当前扫描线段的一部分,则该区间下底边总长以及上下底边个数差更新
flag[o] += d;//更新底边相差差个数
updateCur(o , l , r);//更新底边长
return;
}
int mid = (l + r)>> , ls = o<< , rs = o<<|;
if(mid >= s) update(ls , l , mid , s , t , d);
if(mid+ <= t) update(rs , mid+ , r , s , t , d);
updateCur(o , l , r);
} int bin_search(double key , int n){
int l = , r = n-;
while(l<=r){
int mid = (l+r) >>;
if(x[mid] == key) return mid;
if(x[mid] > key) r=mid-;
else l=mid+;
}
return -;
} int main()
{
// freopen("a.in" , "r" , stdin);
int n,cas=;
double x1,x2,y1,y2;
while(scanf("%d" , &n) , n){
int k=;
for(int i=;i<n;++i){
cin>>x1>>y1>>x2>>y2;
x[k]=x1;
s[k++]=Seg(x1,x2,y1,);
x[k]=x2;
s[k++]=Seg(x1,x2,y2,-);
}
sort(x,x+k);
sort(s,s+k);
int t = unique(x , x+k) - x;
double ans=; for(int i=;i<k;++i){//扫描线段
int pos1 = bin_search(s[i].x1 , t);
/*
这里因为是把它理解成合法线段,所以最右端第 i 个点 , 对应第 i - 1条边
同样道理,在updateCur中,计算有效线段长度时 , 需要x[r+1]
*/
int pos2 = bin_search(s[i].x2 , t)-;
update( , , t- , pos1 , pos2 , s[i].d);//扫描线段时更新底边长度和底边相差个数
ans += sum[]*(s[i+].y-s[i].y);//新增加面积
}
printf("Test case #%d\nTotal explored area: %.2lf\n\n",++cas,ans);
}
return ;
}

HDU 1542 Atlantics 线段树+离散化扫描的更多相关文章

  1. POJ 1151 / HDU 1542 Atlantis 线段树求矩形面积并

    题意:给出矩形两对角点坐标,求矩形面积并. 解法:线段树+离散化. 每加入一个矩形,将两个y值加入yy数组以待离散化,将左边界cover值置为1,右边界置为2,离散后建立的线段树其实是以y值建的树,线 ...

  2. HDU 1542 Atlantis (线段树 + 扫描线 + 离散化)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  3. HDU 1542 - Atlantis - [线段树+扫描线]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1542 Time Limit: 2000/1000 MS (Java/Others) Memory Li ...

  4. hdu 1542 Atlantis(线段树,扫描线)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  5. HDU 4325-Flowers(线段树+离散化)

    题意: 给出每个花开花的时间段,每询问一个时间点输出该时间点开花的数量 分析: 线段树的区间更新,单点查询,但发现时间很大,没法存区间,就想到了离散化. 离散化就是把要处理的数据统一起来重新标号. # ...

  6. HDU 1542 Atlantis(线段树面积并)

     描述 There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. S ...

  7. POJ 1177/HDU 1828 picture 线段树+离散化+扫描线 轮廓周长计算

    求n个图矩形放下来,有的重合有些重合一部分有些没重合,求最后总的不规则图型的轮廓长度. 我的做法是对x进行一遍扫描线,再对y做一遍同样的扫描线,相加即可.因为最后的轮廓必定是由不重合的线段长度组成的, ...

  8. hdu 1542 Atlantis (线段树扫描线)

    大意: 求矩形面积并. 枚举$x$坐标, 线段树维护$[y_1,y_2]$内的边是否被覆盖, 线段树维护边时需要将每条边挂在左端点上. #include <iostream> #inclu ...

  9. Atlantis HDU - 1542 (线段树扫描线)

    There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some ...

随机推荐

  1. bzoj 1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路【Floyd】

    弗洛伊德之后按序列加起来即可 #include<iostream> #include<cstdio> #include<algorithm> using names ...

  2. golang——字符串与编码

    1.字符编码 (1)ASCII码 一个字节表示的英文.数字.标点符号等字符. 国际标准ASCII码为0-127即128个字符,二进制最高位为0,其余为扩展ASCII码. (2)GB2312 两字节,主 ...

  3. C#上机作业及代码Question2

    第二题某文件名为"*.txt",其中*可能由若干个英文单词组成.将此文件名改为"*.dat",并且单词之间用下划线连接,例如: helloworld.txt,改 ...

  4. E - A^B mod C (大数乘方取模)

    Description Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63) ...

  5. E - Cheap Kangaroo(求多个数的最大公约数)

    Description There are N kangaroos going out to eat at an Indian restaurant. The ith kangaroo wants t ...

  6. WCF 相关配置

    WCF错误:413 Request Entity Too Large 在我们用WCF传输数据的时候,如果启用默认配置,传输的数据量过大,经常会出这个错误. WCF包含服务端与客户端,所以这个错误可能出 ...

  7. 页面置换算法-LRU(Least Recently Used)c++实现

    最近最久未使用(LRU)置换算法 #include <iostream> #include <cstdio> #include <cstring> #include ...

  8. MySql学习笔记(2)-简介

    一.什么是MySql MySql是开放源代码的数据库管理系统之一: MySql是一个支持多线程高并发多用户的关系型数据库管理系统: MySql最擅长的是查询性能,而不是事务处理(需要借助第三方存储引擎 ...

  9. LN : leetcode 241 Different Ways to Add Parentheses

    lc 241 Different Ways to Add Parentheses 241 Different Ways to Add Parentheses Given a string of num ...

  10. C++中图片重命名

    非常简单的小程序,满足自己的需求. #include <iostream> #include <fstream> #include<sstream> using n ...