HDU1542Atlantis(扫描线)

题目链接

题目大意:给你n个覆盖矩形,问最后覆盖的面积。

解题思路:将每一个矩形拆成两条线段,一条是+1的,还有一条是减1的。然后扫描先从上往下扫描,碰到加1的那条线段,那么这条线段范围内的节点的覆盖信息就+1,直到碰到减1这个线段范围内的节点的覆盖信息都须要减1。

这样说可能理解不了,就能够画画矩形然后画下扫描线在理解理解。然后就是须要离散化的建树,由于这里是都double型的。所谓离散化建树的意思就是如今每一个叶子节点代表的是一段区间。而不是单独的一点。

代码:

#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <algorithm> using namespace std;
const int maxn = 205; #define lson(x) (x<<1)
#define rson(x) ((x<<1) | 1) struct Node { int l, r, add;
double s;
void set (int l, int r, double s, int add) { this->l = l;
this->r = r;
this->s = s;
this->add = add;
}
}node[4 * maxn]; struct Line { double x, y1, y2;
int flag;
Line (double x, double y1, double y2, int flag) { this->x = x;
this->y1 = y1;
this->y2 = y2;
this->flag = flag;
} bool operator < (const Line &l) const { return x < l.x;
}
}; int n;
vector<Line> L;
vector<double> pos; void pushup(int u) { if (node[u].add)
node[u].s = pos[node[u].r + 1] - pos[node[u].l];
else if (node[u].l == node[u].r)
node[u].s = 0;
else
node[u].s = node[lson(u)].s + node[rson(u)].s;
} void build (int u, int l, int r) { node[u].set (l, r, 0, 0);
if (l == r)
return;
int m = (l + r)>>1;
build(lson(u), l, m);
build(rson(u), m + 1, r);
} void update (int u, int l, int r, int v) { if (node[u].l >= l && node[u].r <= r) {
node[u].add += v;
pushup(u);
return;
} int m = (node[u].l + node[u].r)>>1;
if (l <= m)
update (lson(u), l, r, v);
if (r > m)
update (rson(u), l, r, v);
pushup(u);
} void init () { pos.clear();
L.clear();
double x1, y1, x2, y2; for (int i = 0; i < n; i++) {
scanf ("%lf%lf%lf%lf", &x1, &y1, &x2, &y2);
pos.push_back(y1);
pos.push_back(y2);
L.push_back(Line(x1, y1, y2, 1));
L.push_back(Line(x2, y1, y2, -1));
} sort (pos.begin(), pos.end());
sort (L.begin(), L.end());
pos.erase(unique(pos.begin(), pos.end()), pos.end()); build(1, 0, (int)pos.size() - 1);
} double solve() { init();
double ans = 0;
for (int i = 0; i < (int)L.size() - 1; i++) { int l = lower_bound(pos.begin(), pos.end(), L[i].y1) - pos.begin();
int r = lower_bound(pos.begin(), pos.end(), L[i].y2) - pos.begin();
update (1, l, r - 1, L[i].flag);
// printf ("%.2lf\n", node[1].s);
ans += node[1].s * (L[i + 1].x - L[i].x);
}
return ans;
} int main () { int T = 0;
double x1, y1, x2, y2;
while (scanf ("%d", &n) && n) { printf ("Test case #%d\n", ++T);
printf ("Total explored area: %.2lf\n\n", solve());
}
return 0;
}

HDU1542Atlantis(扫描线)的更多相关文章

  1. HDU1542--Atlantis(扫描线)

    给N个矩形的端点坐标,求矩形覆盖面积和. 原理很简单,从左到右扫描,线段树记录的是纵向覆盖的长度.区间更新.因为坐标是实数而且很大,所以需要离散化. WA+RE+CE+MLE+...一共错了二十多次. ...

  2. HDU1542-Atlantis【离散化&线段树&扫描线】个人认为很全面的详解

    刚上大一的时候见过这种题,感觉好牛逼哇,这都能算 如今已经不打了,不过适当写写题保持思维活跃度还是不错的,又碰到这种题了,想把它弄出来 说实话,智商不够,看了很多解析,花了4.5个小时才弄明白 网上好 ...

  3. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  4. Codeforces VK CUP 2015 D. Closest Equals(线段树+扫描线)

    题目链接:http://codeforces.com/contest/522/problem/D 题目大意:  给你一个长度为n的序列,然后有m次查询,每次查询输入一个区间[li,lj],对于每一个查 ...

  5. HUD 4007 [扫描线][序]

    /* 大连热身B题 不要低头,不要放弃,不要气馁,不要慌张 题意: 坐标平面内给很多个点,放置一个边长为r的与坐标轴平行的正方形,问最多有多少个点在正方形内部. 思路: 按照x先排序,然后确定x在合法 ...

  6. Atitit 图像扫描器---基于扫描线

    Atitit 图像扫描器---基于扫描线 调用范例 * @throws FileExistEx */ public static void main(String[] args) throws Fil ...

  7. 扫描线+堆 codevs 2995 楼房

    2995 楼房  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 地平线(x轴)上有n个矩(lou)形(fan ...

  8. 【BZOJ-4059】Non-boring sequences 线段树 + 扫描线 (正解暴力)

    4059: [Cerc2012]Non-boring sequences Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 440  Solved: 16 ...

  9. 【BZOJ-4422】Cow Confinement 线段树 + 扫描线 + 差分 (优化DP)

    4422: [Cerc2015]Cow Confinement Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 61  Solved: 26[Submi ...

随机推荐

  1. C++友元函数和运算符重载

    非成员友元函数.成员友元函数和友元类 1.友元的作用: (1)友元提供了不同类的成员函数之间.类的成员函数与一般函数之间进行了数据共享的机制: 2.友元的优点和缺点 优点:提高程序的运行效率: 缺点: ...

  2. 离散数学-集合的交并差集运算--STL-set类

    代码其实很简单,我们只需要知道set类的使用方法就可以了,比如迭代器的定义( set<T>::iterator it=a.begin() ),和简单的insert函数插入,以及find函数 ...

  3. 小而美的Promise库——promiz源码浅析

    背景 在上一篇博客[[译]前端基础知识储备--Promise/A+规范](https://segmentfault.com/a/11...,我们介绍了Promise/A+规范的具体条目.在本文中,我们 ...

  4. PADS规则设计-对某一网络/元件单独设置规则

    转载请注明出处,并附带本文网址https://www.cnblogs.com/brianblog/p/9894867.html, 在PADS规则设计中可能会遇到某个走线与另一个走线之间的间距,普通规则 ...

  5. 【ORACLE】查看死锁进程并结束死锁的脚本

    --共享锁:Share:排他锁:Exclusive:行共享锁:Row-S:行排他锁:Row-X select V$SESSION.sid,v$session.SERIAL#,v$process.spi ...

  6. Jquery 1.6+ .prop()与.attr()方法比较

    http://www.cnblogs.com/lujiahong/articles/2289867.html 今天在用JQuery的时候发现一个问题用.attr("checked" ...

  7. 一、SQL基础知识点补充

    SQL DML 和 DDL 可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL). SQL (结构化查询语言)是用于执行查询的语法.但是 SQL 语言也包含用于更新.插 ...

  8. poj1470 Closest Common Ancestors [ 离线LCA tarjan ]

    传送门 Closest Common Ancestors Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 14915   Ac ...

  9. msp430入门编程27

    msp430中C语言开发工具调试程序 msp430入门学习 msp430入门编程

  10. CodeForces 592C The Big Race

    公倍数之间的情况都是一样的,有循环节. 注意min(a,b)>t的情况和最后一段的处理.C++写可能爆longlong,直接Java搞吧...... import java.io.Buffere ...