POJ 2528 Mayor's posters 离散化和线段树题解

版权声明:本文作者靖心,靖空间地址:http://blog.csdn.net/kenden23/,未经本作者允许不得转载。 https://blog.csdn.net/kenden23/article/details/34092597

本题就是要往墙上贴海报,问最后有多少可见的海报。

其实本题的难点并不是线段树,而是离散化。

因为数据很大,直接按原始数据计算那么就会爆内存和时间的。

故此需要把数据离散化。

比如有海报1 6   7 9   20 100  5 1000的原始数据,直接计算需要1-1000的内存,离散化之后只需要8内存,因为只有4组数据8个数。

本题更进一步高级一点的离散化就是需要把不相邻的两个数据插入一个数值,表示有空白的地方,不是所有海报都覆盖到的。

比如上面的数据要离散为:1 2  5 6  7 8 9 10 20 21 100 101 1000,中间插入了一些数值,这样才能保证数据正确。

比较难想出来的地方,需要好好考虑一下才能想通的。看程序discreteArr是离散化之后的数据,使用这样的数据处理就可以比原始数据少很多数据了。


#include <stdio.h>
#include <cstring>
#include <algorithm>
using namespace std;
const int SIZE = 10005;
bool hashColor[SIZE];
int le[SIZE], ri[SIZE];
int discreteArr[SIZE<<2];//因为这里也许需要四倍的SIZE内存
int seg[SIZE<<4];
int visiblePosts;

inline int lChild(int rt) { return rt<<1; }
inline int rChild(int rt) { return rt<<1|1; }

inline void pushDown(int rt)
{
	if (seg[rt])
	{
		seg[lChild(rt)] = seg[rChild(rt)] = seg[rt];
		seg[rt] = 0;
	}
}

void build(int l, int r, int rt)
{
	seg[rt] = 0;
	if (l == r) return ;
	int m = l + ((r-l)>>1);
	build(l, m, lChild(rt));
	build(m+1, r, rChild(rt));
}

void update(int ql, int qr, int col, int l, int r, int rt)
{
	if (ql <= l && r <= qr)
	{
		seg[rt] = col;
		return;
	}
	pushDown(rt);
	int m = l + ((r-l)>>1);
	if (ql <= m) update(ql, qr, col, l, m, lChild(rt));
	if (m < qr) update(ql, qr, col, m+1, r, rChild(rt));
}

void query(int l, int r, int rt)
{
	if (seg[rt])
	{
		if (!hashColor[seg[rt]])
		{
			visiblePosts++;
			hashColor[seg[rt]] = true;
		}
		return ;
	}
	if (l == r) return ;//注意这里没有poster的时候
	int m = l + ((r-l)>>1);
	query(l, m, lChild(rt));
	query(m+1, r, rChild(rt));
}

int biSearch(int arr[], int key, int n)
{
	int l = 1, r = n-1, m = -1;
	while (l <= r)
	{
		m = l + ((r-l)>>1);
		if (arr[m] < key) l = m+1;
		else if (key < arr[m]) r = m-1;
		else break;
	}
	return m;
}

int main()
{
	int T, n;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &n);
		int disN = 1;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d %d", &le[i], &ri[i]);
			discreteArr[disN++] = le[i];
			discreteArr[disN++] = ri[i];
		}
		sort(discreteArr+1, discreteArr+disN);

		int j = 2;
		for (int i = 2; i < disN; i++)
		{
			if (discreteArr[i] != discreteArr[i-1]) 
				discreteArr[j++] = discreteArr[i];
		}
		for (int i = j-1; i > 1; i--)
		{
			if (discreteArr[i] != discreteArr[i-1] + 1)
				discreteArr[j++] = discreteArr[i-1] + 1;
		}
		sort(discreteArr + 1, discreteArr + j);
		build(1, j-1, 1);
		for (int i = 1; i <= n; i++)
		{
			int ql = biSearch(discreteArr, le[i], j);
			int qr = biSearch(discreteArr, ri[i], j);
			update(ql, qr, i, 1, j-1, 1);
		}
		visiblePosts = 0;
		memset(hashColor, 0, sizeof(bool) * (n+1));
		query(1, j-1, 1);
		printf("%d\n", visiblePosts);
	}
	return 0;
}




阅读更多

没有更多推荐了,返回首页