线段树练习题二
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;
}