【SSL 2645】线段树练习题二【线段树变式】

线段树练习题二

Time Limit:10000MS Memory Limit:65536K
Case Time Limit:1000MS

Description

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

在这里插入图片描述

Input

Output

Sample Input

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

Sample Output

4

分析:

通过修改插入函数的参数+一个color参数 表示当前颜色
如果能覆盖把当前颜色赋进数组 其他部分大同小异
最后如果是1 就计数

CODE:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,l,ans,x,y,vis[300001],f[300001];
void insert(int dep,int l,int r,int x,int y,int color){
	if(vis[dep]!=color)
	{
		int mid=(l+r)>>1;
		if(l==x&&r==y)
		{
			vis[dep]=color;return;   //赋值color
		}
		if(vis[dep]>0)
		{
			vis[2*dep]=vis[2*dep+1]=vis[dep];
			vis[dep]=-1;  //-1表示有多种颜色
		}
		if(y<=mid) insert(2*dep,l,mid,x,y,color);
		else if(x>=mid) insert(2*dep+1,mid,r,x,y,color);
		else{
			insert(2*dep,l,mid,x,mid,color);
			insert(2*dep+1,mid,r,mid,y,color);
		}
	}
} 
void cntnum(int dep,int l,int r){
	int mid=(l+r)>>1;
	if(vis[dep]>0){
		f[vis[dep]]=1;return;
	}
	if(r-l>1){
		cntnum(2*dep,l,mid);
		cntnum(2*dep+1,mid,r);
	}
}
int main(){
	scanf("%d%d",&l,&n);
	for(int i=1;i<=n;i++)
	{
		
		scanf("%d%d",&x,&y);
		insert(1,1,l,x,y,i);
	}
	cntnum(1,1,l);
	for(int i=1;i<=n;i++)
	{
		if(f[i]) ans++;  //有就ans++
	}
	cout<<ans;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/dgssl_xhy/article/details/107515813