poj 2528


http://www.cnblogs.com/kevince/p/3893531.html  
线段树,需要离散化
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <map>
#define lson rt << 1, l, m
#define rson rt << 1 | 1, m + 1, r
const int MAXN = 20005;
typedef int ll;
using namespace std;

struct Node
{
	ll l, r, num, lazy;
	ll mid() { return (l + r) >> 1; }
	void setPara(int ll, int rr, int nn, int lz) { l = ll, r = rr, num = nn, lazy = lz; }
} Tree[MAXN * 4];

void buildTree(int rt, int l, int r)
{
	Tree[rt].setPara(l, r, r - l + 1, 0);
	if (l == r)
		return;
	ll m = Tree[rt].mid();
	buildTree(lson);
	buildTree(rson);
}
void push_up(int rt)
{
	Tree[rt].num = max(Tree[rt << 1].num, Tree[rt << 1 | 1].num);
}


bool query(int rt, int l, int r)
{
	if (Tree[rt].num == 0)
		return false;
	if (l <= Tree[rt].l && Tree[rt].r <= r)
	{
		Tree[rt].num = 0;
		return true;
	}
	bool ret = false;
	ll m = Tree[rt].mid();
	if (l > m)
		ret = query(rt << 1 | 1, l, r);
	else if (r <= m)
		ret = query(rt << 1, l, r);
	else
	{
		ret = query(rt << 1, l, m);
		ret |= query(rt << 1 | 1, m + 1, r);
	}
	push_up(rt);
	return ret;
}

int arr[MAXN];//即将被离散化的数组
int ori[MAXN];//arr的副本
int uni[MAXN];//去重后的数组,则离散前的值为uni[x-1]
int discretization(int n)
{
	sort(uni, uni + n);
	int size = unique(uni, uni + n) - uni;
	for (int i = 0; i < n; ++i)
		arr[i] = lower_bound(uni, uni + size, arr[i]) - uni + 1;//arr[i]在原来数组中排第几个,也就是第几大
	return size;
}

int main(void)
{
	freopen("in.txt", "r", stdin);
	freopen("out.txt", "w", stdout);
	int n, T;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%d", &n);
		for (int i = 0; i < 2 * n; i += 2)
			scanf("%d %d", arr + i, arr + i + 1);
		memcpy(uni, arr, sizeof(int) * 2 * n);
		memcpy(ori, arr, sizeof(int) * 2 * n);
		int N = discretization(2 * n);
		buildTree(1, 1, N);
		int ans = 0;
		for (int i = 2 * n - 1; i >= 1; i -= 2)
		{
			if (query(1, arr[i - 1], arr[i]))
				++ans;
		}
		printf("%d\n", ans);
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值