POJ 2528 Mayor's posters 线段树成段更新+离散化

题目来源:POJ 2528 Mayor‘s posters

题意:很多张海报贴在墙上 求可以看到几张海报 看那两张图就行了 第一张俯视图

思路:最多2W个不同的数 离散化一下 然后成段更新 a[rt] = i代表这个区间是第i张报纸 更新玩之后一次query cover[i]=1代表可以看到第i张报纸

#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 20010;
int a[maxn<<2];
int cover[maxn<<2];
struct Point
{
	int x, id, v;
}b[maxn];
int n;
bool cmp1(Point a, Point b)
{
	return a.x < b.x;
}
bool cmp2(Point a, Point b)
{
	return a.id < b.id;
}
void build(int l, int r, int rt)
{
	a[rt] = 0;
	//printf("%d %d\n", l, r);
	if(l+1 == r)
		return;
	int m = (l + r) >> 1;
	build(l, m, rt<<1);
	build(m, r, rt<<1|1);
}
void update(int x, int y, int l, int r, int rt, int num)
{
	;
	if(l == x && r == y)
	{
		a[rt] = num;
		return;
	}
	int m = (l + r) >> 1;
	if(a[rt])
	{
		a[rt<<1] = a[rt];
		a[rt<<1|1] = a[rt];
		a[rt] = 0;
	}
	if(y <= m)
		update(x, y, l, m, rt<<1, num);
	else if(x >= m)
		update(x, y, m, r, rt<<1|1, num);
	else
	{
		update(x, m, l, m, rt<<1, num);
		update(m, y, m, r, rt<<1|1, num);
	}
}

void query(int l, int r, int rt)
{
	if(l+1 == r || a[rt])
	{
			cover[a[rt]] = 1;
		//printf("%d\n", a[rt]);
		return;
	}
	int m = (l + r) >> 1;
	if(a[rt])
	{
		a[rt<<1] = a[rt];
		a[rt<<1|1] = a[rt];
		a[rt] = 0;
	}
	query(l, m, rt<<1);
	query(m, r, rt<<1|1);
}
int main()
{
	int T;

	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &n);
		for(int i = 0; i < n; i++)
		{
			scanf("%d %d", &b[i<<1].x, &b[i<<1|1].x);
			b[i<<1|1].x++;
			b[i<<1].id = i<<1;
			b[i<<1|1].id = i<<1|1;
		}
		sort(b, b+2*n, cmp1);
		int now = b[0].x;
		int sum = 1;
		for(int i = 0; i < 2*n; i++)
		{
			if(b[i].x != now)
			{
				now = b[i].x;
				sum++;
			}
			b[i].v = sum;
		}
		sort(b, b+2*n, cmp2);
		//printf("%d\n", sum);
		//memset(a, 0, sizeof(a));
		build(1, sum, 1);
		//puts("sdsf");
		for(int i = 0; i < n; i++)
		{
			//printf("**%d %d\n", b[i<<1].v, b[i<<1|1].v);
			update(b[i<<1].v, b[i<<1|1].v, 1, sum, 1, i+1);
			//puts("ddsf");
		}
		memset(cover, 0, sizeof(cover));

		query(1, sum, 1);
		int ans = 0;
		for(int i = 1; i <= n; i++)
			if(cover[i])
				ans++;
		printf("%d\n", ans);
	}
	return 0;
}

POJ 2528 Mayor's posters 线段树成段更新+离散化,布布扣,bubuko.com

POJ 2528 Mayor's posters 线段树成段更新+离散化

时间: 2024-08-02 02:41:15

POJ 2528 Mayor's posters 线段树成段更新+离散化的相关文章

POJ训练计划2528_Mayor&#39;s posters(线段树/成段更新+离散化)

解题报告 地址传送门 题意: 一些海报,覆盖上去后还能看到几张. 思路: 第一道离散化的题. 离散化的意思就是区间压缩然后映射. 给你这么几个区间[1,300000],[3,5],[6,10],[4,9] 区间左右坐标排序完就是 1,3,4,5,6,9,10,300000; 1,2,3,4,5,6, 7 ,8; 我们可以把上面的区间映射成[1,8],[2,4],[5,7],[3,6]; 这样就节省了很多空间. 给线段染色, lz标记颜色. #include <map> #include <

POJ训练计划2528_Mayor&amp;#39;s posters(线段树/成段更新+离散化)

解题报告 id=2528">地址传送门 题意: 一些海报,覆盖上去后还能看到几张. 思路: 第一道离散化的题. 离散化的意思就是区间压缩然后映射. 给你这么几个区间[1,300000],[3,5],[6,10],[4,9] 区间左右坐标排序完就是 1,3,4,5,6,9,10,300000; 1,2,3,4,5,6, 7 ,8; 我们能够把上面的区间映射成[1,8],[2,4],[5,7],[3,6]; 这样就节省了非常多空间. 给线段染色, lz标记颜色. #include <ma

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

poj 2528 Mayor&#39;s posters 线段树区间更新

Mayor's posters Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=2528 Description The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at al

POJ 2528 Mayor&#39;s posters(线段树,区间覆盖,单点查询)

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

POJ 2528 Mayor&#39;s posters (hash+线段树成段更新)

题意:有一面墙,被等分为1QW份,一份的宽度为一个单位宽度.现在往墙上贴N张海报,每张海报的宽度是任意的,但是必定是单位宽度的整数倍,且<=1QW.后贴的海报若与先贴的海报有交集,后贴的海报必定会全部或局部覆盖先贴的海报.现在给出每张海报所贴的位置(左端位置和右端位置),问张贴完N张海报后,还能看见多少张海报?(PS:看见一部分也算看到.) 思路:简单的成段更新,但是数据量是1千万,会MT,所以要区间压缩(离散化),保证覆盖的关系不变,离散化的时候有个易错的细节,poj数据水了,这个易错点引用h

POJ 2777 Count Color (线段树成段更新+二进制思维)

题目链接:http://poj.org/problem?id=2777 题意是有L个单位长的画板,T种颜色,O个操作.画板初始化为颜色1.操作C讲l到r单位之间的颜色变为c,操作P查询l到r单位之间的颜色有几种. 很明显的线段树成段更新,但是查询却不好弄.经过提醒,发现颜色的种类最多不超过30种,所以我们用二进制的思维解决这个问题,颜色1可以用二进制的1表示,同理,颜色2用二进制的10表示,3用100,....假设有一个区间有颜色2和颜色3,那么区间的值为二进制的110(十进制为6).那我们就把