POJ2528 线段树+离散化

1. 搞了好久,最后发现是cnd变量没有在每次最后统计时重置。大问题一般经常出现在小地方;
2. 可以用while(c--)来给test的数量计数;
3. 学习了线段树的离散化思想
4. 再给线段树更新时,要注意条件。比如此处的做法是个可行的,检测是否全部覆盖,半覆盖还是未覆盖等。
5. 用-1, 0, 其他 来表示各种着色情况。
参考:

http://www.cppblog.com/Johnnx/archive/2009/10/13/96434.html?opt=admin

http://blog.csdn.net/lyy289065406/article/details/6799170 

#include <iostream>
#include <algorithm>
using namespace std;

struct Goda
{
	int li;
	int num; // color
};

struct Node
{
	int left;
	int right;
	int color; // 1..n:fully covered
};

#define MAX 20000
Node tree[MAX  * 4 + 10];
int colors[10000 + 10];
int cnt = 0;

int se[MAX][2];
Goda line[MAX * 2];

int cmp(const void * a, const void * b)
{
	Goda* x = (Goda*) a;
	Goda* y = (Goda*) b;
	return x->li - y->li;
}

void build(int left, int right, int k)
{
	if (left > right) return;

	tree[k].left = left;
	tree[k].right = right;
	tree[k].color = 0;
	if (left != right)
	{
		int mid = (left + right) / 2;
		build(left, mid, k * 2);
		build(mid + 1, right, k * 2 + 1);
	}
}

void update(int left, int right, int color, int k)
{
	if (left > right) return;
	Node &n = tree[k];

	// no common part
	if (left > n.right || right < n.left) return;
		
	if(n.left >= left && n.right <= right) // fully covered
	{
		n.color = color;
		return;
	}
	
	// partially covered
	if(n.color >= 0)
	{
		int mid = (n.left + n.right) / 2;
		
		tree[2*k].color = n.color ;
		tree[2*k + 1].color = n.color ;
		n.color = -1;
	}

	// multi-color
	update(left, right, color, 2*k);
	update(left, right, color, 2*k + 1);
}

void query(int k)
{
	Node &n = tree[k];
	if (n.color == 0) return;
	if (n.color == -1)
	{
		query(k * 2);
		query(k * 2 + 1);
	}
	else
	{
		if (colors[n.color] == 0)
		{
			cnt++;
			colors[n.color] = 1; // mark
		}
	}
}

int main()
{
	int kase = 0;
	cin >>kase;
	while(kase--)
	{
		int n = 0;
		cin >> n;
		build(1, MAX, 1);
		memset(colors, 0, sizeof(colors));
		memset(line, 0, sizeof(line));

		for (int j = 0; j < n; j++)
		{
			cin >> se[j][0] >> se[j][1];
			line[j * 2].li = se[j][0];
			line[j * 2].num = -j - 1; // start
			line[j * 2 + 1].li = se[j][1];
			line[j * 2 + 1].num = j + 1; // end
		}
		qsort(line, n * 2, sizeof(Goda), cmp);
		int tp = 0;
		int last = -1;
		for (int j = 0; j < n * 2; j++)
		{
			if (line[j].li != last)
			{
				tp++;
				last = line[j].li;
			}
			if (line[j].num > 0)
			{
				se[line[j].num - 1][1] = tp;
			}
			else
			{
				se[- line[j].num - 1][0] = tp;
			}
		}

		for (int j = 0; j < n; j++)
		{
			update(se[j][0], se[j][1], j+1, 1);
		}
		cnt = 0;
		query(1);
		cout << cnt << endl;
	}

	return 0;
}

  

原文地址:https://www.cnblogs.com/lautsie/p/3177020.html