poj 2528 线段树

版权声明:欢迎转载,转载请注明出处,如有错误,还望指出,谢谢 博客地址:https://blog.csdn.net/lanyanzhiji123asd https://blog.csdn.net/lanyanzhiji123asd/article/details/89645135

poj2528

/*
poj2528   贴海报,后面贴的会覆盖前面贴的,问最后有多少张海报不会完全被覆盖
1、首先因为数据很大1e7 ,所以我们离散化处理 
2、我们从后往前判断,因为后面的一定不会被覆盖 
3、我判断的时候是从最上面的区间开始,只要其中有一段区间还没贴海报,说明这段这张海报不会被完全覆盖
4、我用了pushdown和pushup  
pushdown 如果当前区间被覆盖,他下面的左右节点也被覆盖
pushup  如果他的左右节点都被覆盖,那么他也被覆盖 
*/

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<string>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
#define ll long long
const int maxn=200005;
struct node
{
	int left,right,val;
}tree[4*maxn];
int a[maxn],b[maxn],un[maxn],id[10000005];
void build(int L,int R,int num)
{
	tree[num].left=L;
	tree[num].right=R;
	tree[num].val=0;
	if(L==R)
		return ;
	int mid=(L+R)/2;
	build(L,mid,num*2);
	build(mid+1,R,num*2+1);
	
}

void pushdown(int num)
{
	if(tree[num].val)
	{
		tree[num*2].val=1;
		tree[num*2+1].val=1;
	}
}
void pushup(int num)
{
	if(tree[num*2].val&&tree[num*2+1].val)
		tree[num].val=1;
}

int post(int L, int R,int num)
{//cout<<L<<" "<<R<<" "<<tree[num].left<<" "<<tree[num].right<<endl;
	int ans=0;
	if(tree[num].left>=L&&tree[num].right<=R)
	{
		if(!tree[num].val)
		{
			tree[num].val=1;
			return 1;
		}
		else return 0;
			
	}
	pushdown(num);
	int mid=(tree[num].left+tree[num].right)/2;
	//进入他的左右节点判断,只要有一个没有被覆盖我们就可以返回1, ans就是1 
	if(L<=mid)
	{
		if(post(L,R,num*2))
			ans=1;
	}
	if(R>mid)
	{
		if(post(L,R,num*2+1))
			ans=1;
	}
	pushup(num);
	return ans; 
}

int main()
{
 	std::ios::sync_with_stdio(false);
	int t,n,cnt,ans,i;
	scanf("%d",&t);
	while(t--)
	{
		cnt=0,ans=0;
		scanf("%d",&n);
		for(i=0;i<n;i++)
		{
			scanf("%d %d",&a[i],&b[i]);
			un[cnt++]=a[i];
			un[cnt++]=b[i];
		}
		sort(un,un+cnt);
		cnt=unique(un,un+cnt)-un;//离散化处理 
		build(1,cnt,1);
		for(i=0;i<cnt;i++)
			id[un[i]]=i+1;
		for(i=n-1;i>=0;i--)//从后往前遍历 
		{
			if(post(id[a[i]],id[b[i]],1))
			{
//				cout<<id[a[i]]<<"   id  "<<id[b[i]]<<endl;
				ans++;
			}
				
		}
		printf("%d\n",ans);
	} 

 return 0;
}
/*
1
10
20 20
18 18
16 16
14 14
12 12
10 10
8 8
6 6
4 4
2 2

*/

猜你喜欢

转载自blog.csdn.net/lanyanzhiji123asd/article/details/89645135