线段树练习题二(线段树)(未做)

线段树练习题二

Description

桌子上零散地放着若干个不同颜色的盒子,桌子的后方是一堵墙。如右图所示。问从桌子前方可以看到多少个盒子?假设人站得足够远(输入时,由底向上,从左到右)。
在这里插入图片描述

Sample Input

16 //桌子长度
5 // 盒子数量
4 7
12 14
1 5
6 10
11 16

Sample Output

4

Hint

1<=n<=100000,1<=m<=100000,保证坐标范围为[1,n].

AC代码

#include<cstdio>
#include<iostream>
using namespace std;
int n,m,s,f[1000005],cover[1000005];
void insert(int x,int l,int r,int a,int b,int num)
{
	if(cover[x]!=num)
	{
		int mid=(l+r)/2;
		if(l==a&&r==b)cover[x]=num;
		else
		{
			if(cover[x]>=0)
			{
				cover[x*2]=cover[x*2+1]=cover[x];
				cover[x]=-1;
			}
			if(b<=mid)insert(x*2,l,mid,a,b,num);
			else if(a>=mid)insert(x*2+1,mid,r,a,b,num);
			else
			{
				insert(x*2,l,mid,a,mid,num);
				insert(x*2+1,mid,r,mid,b,num);
			}
		}
	}
}
void sc(int x,int l,int r)
{
	int mid=(l+r)/2;
	if(cover[x]>=0)f[cover[x]]=1;
	else if(l+1<r)
	{
		sc(x*2,l,mid);
		sc(x*2+1,mid,r);
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		insert(1,1,n,x,y,i);
	}
	sc(1,1,n);
	for(int i=1;i<=n;i++)
	 s+=f[i];
	cout<<s; 
}

猜你喜欢

转载自blog.csdn.net/weixin_45524309/article/details/107507663