由于区间有重叠,所以我们将区间作为一个结构体

struct region{
    int from;
    int to;
}r[105];

from是区间的起点,to为区间终点。r是一个region的数组。
我们按照区间from由小到大的顺序,将区间排序。比如输入的区间为 300 340;120 310;1 10
排完顺序后的排列为:1 10;120 310;300 340。我们维持一个begin和一个end,这两个变量分别是连续区间的最左边和最右边。
遍历此时排列好的区间,如果此时的区间from在begin和end之间,这说明,这个区间与之间的区间有重叠。此时需要比较这个区间的to与end的大小,如果to>end,则end=to;
如果from并不在begin和end之间,则说明这个区间与之前维持的大区间并不连续,没有重叠,这时,我们只需用剩下的树的个数-之间的区间的的树。同时将begin和end赋值为当前区间的from和to。
直到遍历到最后一个区间,此时直接用剩下的树个数-当前维护的大区间里的树,即可。

#include <iostream>
#include <algorithm>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
struct region{
    int from;
    int to;
}r[105];
int l=10005;    
int m=105;
bool cmp(region a,region b){
    if(a.from!=b.from)
        return a.from<b.from;
}
int end1;
int begin1;
int tree;
int main(int argc, char** argv) {

    while(scanf("%d%d",&l,&m)!=EOF){
    for(int i=0;i<m;i++){
        scanf("%d%d",&r[i].from,&r[i].to);
    }
    sort(r,r+m,cmp);
    end1=r[0].to;
    begin1=r[0].from;
    tree=l+1;
    for(int i=0;i<m;i++){
        if(i==(m-1)){
        tree-=(end1-begin1+1);    
        }
        else{
            if((begin1<=r[i+1].from)&&(r[i+1].from<=end1)){
                if(r[i+1].to>end1){
                    end1=r[i+1].to;
                }
            }
            else{
            tree-=(end1-begin1+1);
            begin1=r[i+1].from;
            end1=r[i+1].to;
            }
        }

    }
    printf("%d\n",tree);     
    }
    return 0;
}

其中我们需要注意的是结构体排序的写法。
这里我用的是sort函数,这个函数的用法为sort(a,a+n)//a是数组的名字,n是长度,sort默认从大到小排序。
如果自己定义的话:sort(a,a+n,cmp)cmp是个函数,里面定义了自己要实现的排序方式,如:
bool cmp(region a,region b){
return a.from<b.from;
}