如果这题道路长1e9,数组开不下,就可以进行离散化处理:记录每次输入的左右端点,将这些点编号,并按照所在位置大小排序。最后遍历完这些点,统计出没砍掉的区间里有多少树。
左端点的position记为1,右端点记为-1.一段区间没砍掉,当且仅当它左边的左端点个数等于右端点个数
因此可以用一个变量sum来记录,sum=0表明这个点左边的左右端点个数相等。

#include <bits/stdc++.h>
using namespace std;
int l,m;
struct node{
    int p;//记录位置,左端点记为1,右端点为-1
    //某个树活着,表明当前这点左边l的个数等于r的个数,即sum(p)=0
    //若某点既是l又是r,就清0
    int a;
}n[100001*2];
int comp(struct node x,struct node y){
    return x.a<y.a;//x的a小,排在前面
}
int main(){
    cin >> l >> m;
    int x,y;
    for(int i=0;i<m;i++){
        cin >> x >> y;
        n[2*i].a=x;
        n[2*i].p+=1;

        n[2*i+1].a=y;
        n[2*i+1].p-=1;
    }
    sort(n,n+2*m,comp);//将区间端点按照位置排序

    int cnt=n[0].a;//从0点到最初的点,这之间的树没被砍掉
    int sum=n[0].p;//sum记录当前的点是否在被砍的区间内
    for(int i=1;i<2*m-1;i++){
        if(sum==0)
            cnt+=n[i].a-n[i-1].a-1;
        sum+=n[i].p;
    }
    cnt+=l-n[2*m-1].a;//最后一个点到终点,这之间的树没被砍掉
    cout << cnt << endl;
    return 0;
}