题目链接
题目分析
先来看一个经典问题,给你
n
个区间,这些区间共覆盖了多少整点,很显然这些点将整条线段分为
那么我们只需要计算每一段是否被覆盖就好了,怎么判断有没有被覆盖呢,很显然当当前段的左边的点中左端点个数比右端点个数多就行了.用cnt 作为计数器,遇到左端点+1,右端点-1,当cnt>0说明当前段会被计算,
那么这道题就很简单了,对A与B分别计数,所要求得就是包含在A中但不包含在B中的区段,重复点想成是长度为0的区段.
AC code
#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define INF 0x3f3f3f3f
#define ALL(x) (x.begin(),x.end())
using namespace std;
typedef long long i64;
typedef pair<i64,i64> Pair;
const int maxn = 1e5 + 10;
typedef pair<int,pair<int,int> > Point;
vector<Point> vec;
int cnt[2];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n,m;
cin>>n>>m;
for(int i=0 ; i<n ; ++i){
int a,b;
cin>>a>>b;
vec.pb(mp(a,mp(0,1)));
vec.pb(mp(b,mp(0,-1)));
}
for(int i=0 ; i<m ; ++i){
int a,b;
cin>>a>>b;
vec.pb(mp(a,mp(1,1)));
vec.pb(mp(b,mp(1,-1)));
}
sort(vec.begin(),vec.end());
//sort(ALL(vec))
cnt[0] = cnt[1] =0;
bool flag = false;
int ans =0;
for(int i=0 ; i<vec.size()-1 ; ++i){
cnt[vec[i].se.fi] += vec[i].se.se;
if(cnt[1]==0 && cnt[0]>0){
ans += vec[i+1].fi-vec[i].fi;
}
//cout<<cnt[0] <<" "<<cnt[1] <<" "<< ans <<"\n";
}
// for(auto ele : vec){
// cout<<ele.fi <<" "<<ele.se.fi <<" "<<ele.se.se <<"\n";
// }
cout<<ans<<"\n";
return 0;
}