好久没写过博客了,这学期不是很有热情去写博客,写过的题也懒得写题解。现在来水一水博客,写一下若干年前的题目的题解。

Atlantis

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 21978    Accepted Submission(s): 8714

Problem Description
There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of parts of the island. But unfortunately, these maps describe different regions of Atlantis. Your friend Bill has to know the total area for which maps exist. You (unwisely) volunteered to write a program that calculates this quantity.
 
Input
The input file consists of several test cases. Each test case starts with a line containing a single integer n (1<=n<=100) of available maps. The n following lines describe one map each. Each of these lines contains four numbers x1;y1;x2;y2 (0<=x1<x2<=100000;0<=y1<y2<=100000), not necessarily integers. The values (x1; y1) and (x2;y2) are the coordinates of the top-left resp. bottom-right corner of the mapped area.

The input file is terminated by a line containing a single 0. Don’t process it.

 
Output
For each test case, your program should output one section. The first line of each section must be “Test case #k”, where k is the number of the test case (starting with 1). The second one must be “Total explored area: a”, where a is the total explored area (i.e. the area of the union of all rectangles in this test case), printed exact to two digits to the right of the decimal point.

Output a blank line after each test case.

 
Sample Input
2
10 10 20 20
15 15 25 25.5
0
 
Sample Output
Test case #1
Total explored area: 180.00
 
Source
 
 
题目就是求矩形面积并。扫描线。
一开始不知道扫描线是个什么东西的时候,感觉很厉害的东西,知道是什么之后,就。。。
就是区间更新的问题,因为在这里线段树维护的是线段,不是点,所以每个点代表的其实是一条线段,所以会有什么+1,-1的操作。
 
具体的看代码。
 
代码:

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e4+;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 int cnt[maxn<<];
double sum[maxn<<],f[maxn]; void init()
{
memset(cnt,,sizeof cnt);
memset(sum,,sizeof sum);
} struct node{
double h,l,r;
int s; node(){} node(double a,double b,double c,int d):l(a),r(b),h(c),s(d){} bool operator<(const node&cmp){
return h<cmp.h;
} }line[maxn]; void pushup(int rt,int l,int r)
{
if(cnt[rt]){//解决线段重复问题,如果当前区间有标记,那么就用f数组进行更新,不是左右儿子更新
sum[rt]=f[r+]-f[l];
}
else if(l==r){
sum[rt]=;
}
else{
sum[rt]=sum[rt<<]+sum[rt<<|];
}
} void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l&&r<=R){
cnt[rt]+=c;
pushup(rt,l,r);
return ;
} int m=(l+r)>>;
if(L<=m) update(L,R,c,lson);
if(R> m) update(L,R,c,rson);
pushup(rt,l,r);
} int main()
{
int n,cas=;
while(~scanf("%d",&n)&&n){
int h=;
for(int i=;i<=n;i++){//从下往上扫
double a,b,c,d;
scanf("%lf%lf%lf%lf",&a,&b,&c,&d);
f[h]=a;
line[h++]=node(a,c,b,);//标记入边
f[h]=c;
line[h++]=node(a,c,d,-);//标记出边
}
sort(f,f+h);
sort(line,line+h);
int d=unique(f,f+h)-f;//离散化
init();
double ret=;
for(int i=;i<h-;i++){//因为每一个点代表的是线段,0代表0-1这一段,所以是查询的时候-1
int l=lower_bound(f,f+d,line[i].l)-f;//直接用下标进行操作
int r=lower_bound(f,f+d,line[i].r)-f;
r--;//因为线段树上点代表线段,从i到i+1这一段,所以查询的时候,右边要-1
if(l<=r) update(l,r,line[i].s,,d-,);
ret+=sum[]*(line[i+].h-line[i].h);
}
printf("Test case #%d\n",cas++);
printf("Total explored area: %.2f\n\n",ret);
}
return ;
}

开溜。

HDU 1542.Atlantis-线段树求矩形面积并(离散化、扫描线/线段树)-贴模板的更多相关文章

  1. HDU - 1255 覆盖的面积(线段树求矩形面积交 扫描线+离散化)

    链接:线段树求矩形面积并 扫描线+离散化 1.给定平面上若干矩形,求出被这些矩形覆盖过至少两次的区域的面积. 2.看完线段树求矩形面积并 的方法后,再看这题,求的是矩形面积交,类同. 求面积时,用被覆 ...

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

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

  3. POJ 1151 Atlantis 线段树求矩形面积并 方法详解

    第一次做线段树扫描法的题,网搜各种讲解,发现大多数都讲得太过简洁,不是太容易理解.所以自己打算写一个详细的.看完必会o(∩_∩)o 顾名思义,扫描法就是用一根想象中的线扫过所有矩形,在写代码的过程中, ...

  4. 【hdu1542】线段树求矩形面积并

    分割线内容转载自http://hzwer.com/879.html ------------------------------------------------------------------ ...

  5. 【hdu1255】线段树求矩形面积交

    题意大概就是上图这个样子.<=100组测试数据,每组<=1000个矩形. 题解: 这个问题怎么解决..做了上一题矩形面积并应该就会了.. 对于每个节点维护3个值: cnt:该节点所代表的这 ...

  6. POJ 1151Atlantis 扫描线+线段树求矩形面积并

    题目链接 #include <iostream> #include <vector> #include <cstdio> #include <cstring& ...

  7. hdu1255 覆盖的面积 线段树+里离散化求矩形面积的交

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1255 求矩形面积的交的线段树题目,刚做了求并的题目,再做这个刚觉良好啊,只要再加一个表示覆盖次数大于1 ...

  8. UVA 11983 Weird Advertisement --线段树求矩形问题

    题意:给出n个矩形,求矩形中被覆盖K次以上的面积的和. 解法:整体与求矩形面积并差不多,不过在更新pushup改变len的时候,要有一层循环,来更新tree[rt].len[i],其中tree[rt] ...

  9. (HDU 1542) Atlantis 矩形面积并——扫描线

    n个矩形,可以重叠,求面积并. n<=100: 暴力模拟扫描线.模拟赛大水题.(n^2) 甚至网上一种“分块”:分成n^2块,每一块看是否属于一个矩形. 甚至这个题就可以这么做. n<=1 ...

随机推荐

  1. java之spring mvc之helloworld

    这篇主要讲解springmvc的基本的使用,这里以helloworld项目为例. 目录结构: 1. 新建 web 项目 :springmvc_helloworld 2. 在 WebRoot\WEB-I ...

  2. Nas 系统的虚拟化方案

    Nas 系统的虚拟化方案 https://zhuanlan.zhihu.com/p/55025102 对搞技术的人来说,Nas 是个理想的玩具,既然是程序员用的 Nas ,自然要专业一点,不能像小白一 ...

  3. integer 面试题。

    上面输出的结果是:true true ----------------------------------------------------- false true 因为-128-127是byte的 ...

  4. P2472 [SCOI2007]蜥蜴 (最大流)

    题目 P2472 [SCOI2007]蜥蜴 解析 这个题思路比较清晰,本(qi)来(shi)以(jiu)为(shi)无脑建图跑最大流,结果挂了,整了一个小时后重新建图才过的. 建立一个超级源点和一个超 ...

  5. Spring的核心机制:依赖注入

    依赖注入的概念 当一个对象要调用另一个对象时,一般是new一个被调用的对象,示例: class  A{ private B b=new B(); public  void  test(){ b.say ...

  6. linux tomcat 启动后控制台未显示启动日志

    在linux 服务器启动的时候未出现启动日志,这个时候,如果执行startup.sh会出现控制台没有打印任何消息的问题 应该执行: ./catalina.sh run

  7. 19,flask消息闪现-flash

    Flash消息 请求完成后给用户的提醒消息,flask的核心特性, flash函数实现效果 视图函数中调用flash()方法 html中要使用get_flashed_messages() 后端代码: ...

  8. jquery 子元素筛选选择器

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-type" content ...

  9. Lovers(HDU6562+线段树+2018年吉林站)

    题目链接 传送门 题意 初始时有\(n\)个空串,然后进行\(q\)次操作,操作分为以下两种: wrap l r x:把\(l,r\)中的每个字符串的首尾都加入\(x\),如\(s_i=121,x=3 ...

  10. Android init介绍(下)

    上一篇请参考<Android init介绍(上)> 5. AIL 在init启动过程中,系统服务等均是通过解析rc文件来启动,而rc文件则是由Android初始化语言(Android In ...