HDU 3265 Posters(线段树)

HDU 3265 Posters

题目链接

题意:给定一些矩形海报,中间有孔,求贴海报的之后的海报覆盖面积并

思路:海报一张可以切割成4个矩形,然后就是普通的矩形面积并了,利用线段树维护即可

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;

const int N = 50005;

struct Node {
	int l, r, len, cover;
	int size() {return r - l + 1;}
} node[N * 4];

struct Line {
	int l, r, y, flag;
	Line() {}
	Line(int l, int r, int y, int flag) {
		this->l = l; this->r = r;
		this->y = y; this->flag = flag;
	}
} line[N * 8];

struct Rec {
	int x1, y1, x2, y2;
	Rec() {}
	Rec(int x1, int y1, int x2, int y2) {
		this->x1 = x1; this->y1 = y1;
		this->x2 = x2; this->y2 = y2;
	}
} rec[N * 4];

bool cmp(Line a, Line b) {
	return a.y < b.y;
}

int n;
int x[4], y[4];

#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)

void pushup(int x) {
	if (node[x].cover) node[x].len = node[x].size();
	else if (node[x].l == node[x].r) node[x].len = 0;
	else node[x].len = node[lson(x)].len + node[rson(x)].len;
}

void build(int l, int r, int x = 0) {
	node[x].l = l; node[x].r = r;
	if (l == r) {
		node[x].cover = node[x].len = 0;
		return;
	}
	int mid = (l + r) / 2;
	build(l, mid, lson(x));
	build(mid + 1, r, rson(x));
	pushup(x);
}

void add(int l, int r, int v, int x = 0) {
	if (l > r) return;
	if (node[x].l >= l && node[x].r <= r) {
		node[x].cover += v;
		pushup(x);
		return;
	}
	int mid = (node[x].l + node[x].r) / 2;
	if (l <= mid) add(l, r, v, lson(x));
	if (r > mid) add(l, r, v, rson(x));
	pushup(x);
}

int main() {
	while (~scanf("%d", &n) && n) {
		build(0, 50000);
		int rn = 0, ln = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < 4; j++)
				scanf("%d%d", &x[j], &y[j]);
			rec[rn++] = Rec(x[0], y[0], x[1], y[2]);
			rec[rn++] = Rec(x[0], y[2], x[2], y[3]);
			rec[rn++] = Rec(x[0], y[3], x[1], y[1]);
			rec[rn++] = Rec(x[3], y[2], x[1], y[3]);
		}
		for (int i = 0; i < rn; i++) {
			line[ln++] = Line(rec[i].x1, rec[i].x2, rec[i].y1, 1);
			line[ln++] = Line(rec[i].x1, rec[i].x2, rec[i].y2, -1);
		}
		n = ln;
		sort(line, line + n, cmp);
		ll ans = 0;
		for (int i = 0; i < n; i++) {
			if (i) ans += (ll)node[0].len * (line[i].y - line[i - 1].y);
			add(line[i].l, line[i].r - 1, line[i].flag);
		}
		printf("%lld\n", ans);
	}
	return 0;
}
时间: 2025-01-14 11:21:27

HDU 3265 Posters(线段树)的相关文章

HDU 3265 Posters (线段树+扫描线)(面积并)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3265 给你n个中间被挖空了一个矩形的中空矩形,让你求他们的面积并. 其实一个中空矩形可以分成4个小的矩形,然后就是面积并,特别注意的是x1 == x3 || x2 == x4的时候,要特判一下,否则会RE. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algori

hdu 1828 Picture(线段树&amp;扫描线&amp;周长并)

Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2578    Accepted Submission(s): 1363 Problem Description A number of rectangular posters, photographs and other pictures of the same shap

POJ 2528 Mayor&#39;s posters (线段树区间更新+离散化)

题目链接:http://poj.org/problem?id=2528 给你n块木板,每块木板有起始和终点,按顺序放置,问最终能看到几块木板. 很明显的线段树区间更新问题,每次放置木板就更新区间里的值.由于l和r范围比较大,内存就不够了,所以就用离散化的技巧 比如将1 4化为1 2,范围缩小,但是不影响答案. 写了这题之后对区间更新的理解有点加深了,重点在覆盖的理解(更新左右两个孩子节点,然后值清空),还是要多做做题目. 1 #include <iostream> 2 #include <

Poj 2528 Mayor&#39;s posters (线段树+离散化)

题目连接: http://poj.org/problem?id=2528 题目大意: 有10000000块瓷砖,n张海报需要贴在墙上,每张海报所占的宽度和瓷砖宽度一样,长度是瓷砖长度的整数倍,问按照所给海报顺序向瓷砖上贴海报,最后有几张海报是可见的? 解题思路: 因为瓷砖块数和海报张数多,首选线段树,如果按照常规的建树方式,把瓷砖当做数的节点,肯定会MTL......... 所以我们可以用海报的起点和终点当做树的节点,这样树的节点才有20000个,但是这样建树的话,求海报覆盖了那些节点会很复杂,

poj 2528 Mayor&#39;s posters(线段树)

题目链接:http://poj.org/problem?id=2528 思路分析:线段树处理区间覆盖问题,也可以看做每次给一段区间染不同的颜色,最后求在整段区间上含有的所有颜色种类数: 注意由于区间太大,所以需要离散化: 区间更新:对于线段树的每个结点,标记颜色,初始时没有颜色,标记为0:当更新时,使用延迟标记,需要标记传递到子节点: 区间查询:使用深度优先查询线段树,当某个子节点的颜色不为0时,即停止深度优先搜索,并在map中查询是否已经记录该段区间的颜色: 代码如下: #include <i

Poj2528Mayor&#39;s posters线段树

先贴,明天再补. #include <cstdio> #include <cstring> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #include <cstdlib> #include <list> #include <set> #inclu

poj2528--Mayor&#39;s posters(线段树+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41785   Accepted: 12164 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post

HDU 1542 Atlantis 线段树+离散化+扫描线

题意:给出一些矩形的最上角坐标和右下角坐标,求这些矩形的面积并. NotOnlySuccess 线段树专辑中扫描线模板题,弱智的我对着大大的代码看了一下午才搞懂. 具体见思路见注释=.= #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #define lson rt<<1,l,mid #define rson rt<<1|1,mid

POJ2528Mayor&#39;s posters[线段树 离散化]

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 59683   Accepted: 17296 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral post