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;

}

  

你可能感兴趣的:(poj)