poj2528(線段樹區間更新)

#include <iostream>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<math.h>
using namespace std;
const int M = 2*1e4 + 10;
const int N = 1e6;
int f[M][2];
int co[M];
typedef struct
{
	int cover;
	int left, right;
}P;
P p[4*M];
typedef struct
{
	int num;
	int p;
}Q;
Q q[2 * M];
bool cmp(const Q&a, const Q&b)
{
	return a.num<b.num;
}
void build(int L, int R, int k)
{
	p[k].left = L;
	p[k].right = R;
	p[k].cover = 0;
	if (L == R)
		return;
	int mid = (L + R) >> 1;
	build(L, mid, k << 1);
	build(mid + 1, R, k << 1 | 1);
}
void update(int L, int R, int id, int d)
{
	if (p[id].left == L&&p[id].right == R)
	{
		p[id].cover = d;
		return;
	}
	if (p[id].cover>0)
	{
		p[id << 1].cover = p[id].cover;
		p[id << 1 | 1].cover = p[id].cover;
		p[id].cover = 0;
	}
	int mid = (p[id].left + p[id].right) >> 1;
	if (R <= mid)
		update(L, R, id << 1, d);
	if (L>mid)
		update(L, R, id << 1 | 1, d);
	if (L <= mid&&R>mid)
	{
		update(L, mid, id << 1, d);
		update(mid + 1, R, id << 1 | 1, d);
	}
}
void query(int d)
{
	if (p[d].cover>0)
	{
		co[p[d].cover] = 1;
		p[d].cover=0;
		return;
	}
	if (p[d].left == p[d].right)
		return;
	query( d << 1 );
	query( d << 1 | 1 );
}
int main()
{
	int T, n;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &n);
		memset(f,0,sizeof(f));
		for (int i = 1; i <= n; i++)
		{
			scanf("%d%d", &f[i][0], &f[i][1]);
			q[2 * i - 1].num = f[i][0];
			q[2 * i - 1].p = i;
			q[2 * i].num = f[i][1];
			q[2 * i].p = -1 * i;
		}
		sort(q + 1, q +1+ 2 * n, cmp);
		int temp = q[1].num, t = 1;
		for (int i = 1; i <= 2 * n; i++)
		{
			if (temp != q[i].num)
			{
				t++;
				temp = q[i].num;
			}
			if (q[i].p>0)
				f[q[i].p][0] = t;
			else
				f[q[i].p*-1][1] = t;
		}
		//for(int i=1;i<=n;i++)
		  //cout<<f[i][0]<<" "<<f[i][1]<<endl;cout<<"t= "<<t<<endl;
		build(1, t, 1);
		for (int i = 1; i <= n; i++)
			update(f[i][0], f[i][1], 1, i);
		memset(co, 0, sizeof(co));
		int ans = 0;
		query(1);
		for (int i = 1; i <=  t; i++)
			if (co[i] == 1)
				ans++;
		printf("%d\n", ans);
	}

	return 0;
}

這題是典型的線段樹區間更新,不過有一個點需要注意,在建樹之間需要把數據離散化,因爲數據範圍過大,直接建樹會超內存,不信可以試試

這裏首先講下如何把數據進行離散化。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章