第一种:暴力破解 
for(i:1~M) 
    for(j:区间长度) 
对于本题数据L(1 <= L <= 10000)和 M(1 <= M <= 100),时间复杂度最大为O(M*L),可以ac;
但如果数据范围扩大,此方法则行不通。

第二种:差分记录每个点被区域覆盖的次数,覆盖0次的点则有树。
#include<iostream>
using namespace std;
int delta[10010];    //差分:记录每一个点与前一个点上区域覆盖的次数之差,
                         //其值表示当前点被区域覆盖的次数
int main(){
    int l;    //马路的长度
    int m;    //区域的数目
    
    cin >> l >> m;
    for(int i = 0; i < m; i++){
        int start, end;
        cin >> start >> end;
        if(start <= end){//当起始点 <= 终止点时
            delta[start]++;    //起始点比其前一个点多被覆盖一次
            delta[end+1]--;    //终止点的后一个点比终止点少被覆盖一次
        }
        else{
            delta[end]++;
            delta[start+1]--;
        }
    }
    int sum = 0;    //树的数目总和
    int a = 0;    //记录当前点被区域覆盖的次数
    for(int i = 0; i <= l; i++){
        a += delta[i];
        if(a == 0){
            sum++;
        }
    }
    
    cout << sum <<endl;
    return 0;
}
第三种:将各区域按起始端点从大到小进行排序,合并有交集的区域,再计算减去每块区域移走树木的数量。
#include<iostream>
#include<algorithm>
using namespace std;
struct area{
    int start;
    int end;
}a[110];
bool comp(area a, area b){
    if(a.start < b.start)
        return 1;
    else
        return 0;
}
int main(){
    int l, m;
    cin >> l >> m;
    for(int i = 0; i < m; i++){
        cin >> a[i].start >> a[i].end;
    }
    sort(a, a + m, comp); //将区域按照起始端点从左到右排序
    int left = a[0].start;    //记录一个区域的左端点
    int right = a[0].end;     //记录一个区域的右端点
    int cnt = l + 1;    //刚开始有l+1棵树
    for(int i = 1; i < m; i++){
        if(a[i].start < right){//当前区域与上一区域有交集
            right = max(right, a[i].end);
        }
        else{//当前区域与上一区域无交集
            cnt -= right - left + 1;    //减去上一个连续的区域中移走的树
            left = a[i].start;    //更新当前区域端点值
            right = a[i].end;
        }
    }
    //考虑最后一个区域的情况
    cnt -= right - left + 1;
    cout << cnt << endl;
}
第四种:创建结构体,只维护端点的位置和端点的差分值,a += delta[i]  当a == 0时,i为每个不连续的区域起始点的前一个点,则 (a == 1 && delta[i] == 1) i为每个不连续的区域的起始点。由此可以计算出树的数量,记得要加上最后一个终止点到路尽头的树。
#include<iostream>
#include<algorithm>
using namespace std;
struct area{
    int pos;    //区域端点的位置
    int num;    //区域端点与前一个点的差值
}delta[220];
bool comp(area a, area b){
    if(a.pos < b.pos)
        return 1;
    else
        return 0;
}
int main(){
    int l, m;
    cin >> l >> m;
    int start, end;
    for(int i = 0; i < m; i++){//维护每个端点的差分值,起始点则+1,终止点的下一个点则-1
        cin >> start >> end;
        delta[i].pos = start;
        delta[i].num = 1;
        delta[i+m].pos = end + 1;
        delta[i+m].num = -1;
    }
    sort(delta, delta+2*m, comp); //将结构体中维护的端点从左到右排序
    int a = 0;    //记录当前点的状态
    int cnt = 0;  //记录树的数量
    for(int i = 0; i < 2*m; i++){
        a += delta[i].num;    //
        if(a == 1 && delta[i].num == 1){//当前点为区域的起始点
            cnt += delta[i].pos - delta[i-1].pos;    //区域起始点 - 上一个区域终止点的下一个点 = 树的数量
        }
    }
    //考虑最后一个端点到路尽头的情况
    cnt += l - delta[2*m-1].pos + 1;
    cout << cnt << endl;
}