链接:点击打开链接
题意:给定两个区间集合 A 和 B,其中集合 A 包含 N 个区间[ A1, A2 ], [ A3, A4 ], ..., [ A2N-1, A2N ],集合 B 包含 M 个区间[ B1, B2 ], [ B3, B4 ], ..., [ B2M-1, B2M ]。求 A - B 的长度。
例如对于 A = {[2, 5], [4, 10], [14, 18]}, B = {[1, 3], [8, 15]}, A - B = {(3, 8), (15, 18]},长度为8。
代码:
#include <queue>
#include <vector>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
struct node{
int id,le,x;
friend bool operator<(node a,node b){
return a.x<b.x;
}
}s[500005];
int main(){ //直接将所有点进行排序,进行打标记
int n,m,i,j,u,ans,sum1,sum2; //区分是哪一种点的左端还是右端,用
while(scanf("%d%d",&n,&m)!=EOF){ //两个值分别维护两种点的值
u=0;
for(i=1;i<=n;i++){
scanf("%d",&s[u].x);
s[u].id=1,s[u].le=1;
u++;
scanf("%d",&s[u].x);
s[u].id=1,s[u].le=2;
u++;
}
for(i=1;i<=m;i++){
scanf("%d",&s[u].x);
s[u].id=2,s[u].le=1;
u++;
scanf("%d",&s[u].x);
s[u].id=2,s[u].le=2;
u++;
} //标记是左端还是右端
sort(s,s+u);
ans=sum1=sum2=0;
for(i=0;i<=u-1;i++){
if(s[i].id==1){ //遇到第一种点的左端点就加一,右端点就减一
if(s[i].le==1) //第二种点也是一样,当区间中sum1>0&&sum2<0
sum1++; //时就是A-B的一部分
else //详细题解可以看hiho一下第152周的讨论,里面
sum1--; //有很详细的讲解
}
else{
if(s[i].le==1)
sum2++;
else
sum2--;
}
if(sum1>0&&sum2==0)
ans+=(s[i+1].x-s[i].x);
}
printf("%d\n",ans);
}
return 0;
}