[线段树]线段树练习题二
线 段 树 练 习 题 二 线段树练习题二 线段树练习题二
题目描述
桌子上零散地放着若干个不同颜色的盒子,桌子的后方是一堵墙。如右图所示。问从桌子前方可以看到多少个盒子?假设人站得足够远(输入时,由底向上,从左到右)。
样例输入
16 //桌子长度
5 // 盒子数量
4 7
12 14
1 5
6 10
11 16
样例输出
4
数据范围
1<=n<=100000,1<=m<=100000,保证坐标范围为[1,n].
code
#include<stdio.h>
#include<iostream>
using namespace std;
int n,m,l,r,f[400001]={0},tr[400001]={0},ans=0;
void countt(int t,int a,int b);
void insertt(int t,int a,int b,int x,int y,int c);
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
scanf("%d%d",&l,&r);
insertt(1,1,n,l,r,i);
}
countt(1,1,n);
for(int i=1;i<=m;i++)if(f[i])ans++;
printf("%d",ans);
return 0;
}
void countt(int t,int a,int b){
int mid=(a+b)/2;
if(tr[t]>=0) f[tr[t]]=1;
else if(a+1<b)countt(t*2,a,mid),countt(t*2+1,mid,b);
}
void insertt(int t,int a,int b,int x,int y,int c){
if(tr[t]!=c){
int mid=(a+b)/2;
if(a==x and b==y)tr[t]=c;
else{
if(tr[t]>=0){
tr[t*2]=tr[t*2+1]=tr[t];
tr[t]=-1;
}
if(y<=mid)insertt(t*2,a,mid,x,y,c);
else if(x>=mid)insertt(t*2+1,mid,b,x,y,c);
else insertt(t*2,a,mid,x,mid,c),insertt(t*2+1,mid,b,mid,y,c);
}
}
}