主要思想是区间排序,首先从大到小对区间(要挖树的区间)的尾部进行排序,这时候如果区间有重叠的话,区间尾部就是最大的那个,我们只需要找到区间的开始即可。如果我们目前区间的开始比后面区间的尾部要大,这说明这两个区间不存在重叠,我们不需要考虑,但如果要大的话,说明上下两个区间重叠,则我们要找到头部小的那一个,类似于选择排序。

include<stdio.h>

include<math.h>

typedef struct road{
int begin;
int end;
int tree;
}road;
int max(int a,int b){
if(a>=b)return a;
else return b;
}
int m=0;
int main(){
int M,L,cutedTree=0,begin,end;
scanf("%d%d",&M,&L);
road myRoad[L];
for(int i=0;i<L;i++){
scanf("%d%d",&myRoad[i].begin,&myRoad[i].end);
if(myRoad[i].begin>myRoad[i].end){
int tmp=myRoad[i].begin;
myRoad[i].begin=myRoad[i].end;
myRoad[i].end=tmp;
}
myRoad[i].tree=myRoad[i].end-myRoad[i].begin+1;
}
for(int i=0;i<L-1;i++){
for(int j=0;j<L-i-1;j++){
if(myRoad[j].end<myRoad[j+1].end){
road tmp=myRoad[j];
myRoad[j]=myRoad[j+1];
myRoad[j+1]=tmp;
}
}
}
M++;
while(m < L){
end=myRoad[m].end;
begin=myRoad[m].begin;
while(begin<=myRoad[m].end){
if(m<L){
if(begin>myRoad[m].begin){
begin=myRoad[m].begin;
}}
m++;
}
M-=(end-begin+1);
}
printf("%d",M);
}

下面换一种简单的方法,即差分。初始数组数据为10000000000……,数字代表该位置数据与前一位置数据的差分,还原成原来的数据即111111111111……,每次输入m,n,则让m个位置-1,n+1个位置+1,使得差分仍然成立,最后差分求前缀和,还原数组
#include<stdio.h>
#include<math.h>

int main(){
int L,M;
scanf("%d%d",&L,&M);
int a[10002]={0};
a[0]=1;
int m,n;
for(int i=0;i<M;i++){
scanf("%d%d",&m,&n);
a[m]--;
a[n+1]++;
}
int num=0;
if(a[0]==1)
num++;
for(int i=1;i<=L;i++){
a[i]=a[i]+a[i-1];
if(a[i]==1)num++;
}
printf("%d",num);
}

最后我们尝试离散化(如果L特别大的话数组开不下,则采用离散化,因为我们发现差分后数据的数值其实只和端点有关,中间的0000000000000可忽略)

include<stdio.h>

include<math.h>

int main(){
int L,M;
scanf("%d%d",&L,&M);
typedef struct tree{
int loc;
int num;
}tree;
tree myTree[200002];
myTree[0].loc=0;
myTree[0].num=1;
myTree[1].loc=L;
myTree[1].num=0;
int m,n,p=2;
for(int i=0;i<M;i++){
scanf("%d%d",&m,&n);
myTree[p].loc=m;
myTree[p].num--;
p++;
myTree[p].loc=n+1;
myTree[p].num++;
p++;
}

tree haha;
for(int i=0;i<p-1;i++){
    for(int j=0;j<p-i-1;j++){
        if(myTree[j].loc>myTree[j+1].loc){
            haha=myTree[j];
            myTree[j]=myTree[j+1];
            myTree[j+1]=haha;
        }
    }
}



int num=myTree[0].num,Tree=0,i=0;
while(myTree[i+1].loc==myTree[i].loc){
    i++;
    num+=myTree[i].num;
}
if(num==1){
    Tree+=(myTree[i+1].loc-myTree[i].loc);
}


for(i++;i<p-1;i++){
num+=myTree[i].num;
while(myTree[i+1].loc==myTree[i].loc){
    i++;
    num+=myTree[i].num;
}
if(num==1){
    Tree+=(myTree[i+1].loc-myTree[i].loc);
}

}
if(myTree[p-1].num==0) Tree++;
printf("%d",Tree);

}