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;
}

这题是典型的线段树区间更新,不过有一个点需要注意,在建树之间需要把数据离散化,因为数据范围过大,直接建树会超内存,不信可以试试

这里首先讲下如何把数据进行离散化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值