[线段树]线段树练习题二

线 段 树 练 习 题 二 线段树练习题二 线


题目描述

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


样例输入

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);
        }
    }
}

posted @ 2020-08-07 10:19  unknown_future  阅读(55)  评论(0编辑  收藏  举报