题目:
C - 经典问题
You are given two interval collections A and B. Collection A has N intervals [ A1, A2 ], [ A3, A4 ], …, [ A2N-1, A2N ] and collection B has M intervals [ B1, B2 ], [ B3, B4 ], …, [ B2M-1, B2M ]. Your task is to calculate the length of A - B.
For example if A = {[2, 5], [4, 10], [14, 18]} and B = {[1, 3], [8,|15]}, the length of A - B ({(3, 8), (15, 18]}) is 8.
Input
Line 1: Two integers N and M (1 ≤ N, M ≤ 100000).
Line 2: 2*N integers, A1, A2, ..., A2N (1 ≤ Ai ≤ 100000000).
Line 3: 2*M integers, B1, B2, ..., B2M (1 ≤= Bi ≤ 100000000).
Output
The length of A - B.
Sample Input
3 2
2 5 4 10 14 18
1 3 8 15
Sample Output
8
分析:
题目的意思啊大概就是求区间集 A - B = A - A∩B. 将所有的区间端点在数轴上离散化,并做好相应标记(是A中还是B中的端点,记作A/B,是左端点还是右端点,记作L/R).
对于离散的点,从小到大遍历,如果满足BL = BR(B集的是个完整区间)并且AL > AR(A集的区间左端点多于右端点,说明右边必存在一端点覆盖左边B集完整区间),则用下一个端点减去当前端点.
代码:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const int MAXN = 1e6 + 10;
int n,m;
struct node{
ll val;
char id[3];
bool operator <(const node &t)const{
return val < t.val;
}
}rec[MAXN];
int main(){
std::ios::sync_with_stdio(false);
std::cin.tie(0);
while(cin>>n>>m){
int cnt = 0;
for(int i=1;i<=n;i++){
ll l,r;
cin>> l >> r;
rec[cnt].val = l,rec[cnt].id[0] = 'A',rec[cnt].id[1] = 'L';
cnt++;
rec[cnt].val = r,rec[cnt].id[0] = 'A',rec[cnt].id[1] = 'R';
cnt++;
}
for(int i=1;i<=m;i++){
ll l,r;
cin>> l >> r;
rec[cnt].val = l,rec[cnt].id[0] = 'B',rec[cnt].id[1] = 'L';
cnt++;
rec[cnt].val = r,rec[cnt].id[0] = 'B',rec[cnt].id[1] = 'R';
cnt++;
}
sort(rec,rec+2*(n+m));//区间排序
//for(int i=0;i<2*(m+n);i++)cout<< rec[i].val;
ll ans = 0;
ll AL = 0,AR = 0,BL = 0,BR = 0;
for(int i=0;i<2*(m+n);i++){
node e = rec[i];
if(e.id[0] == 'A'){
if(e.id[1] == 'L')AL++;
else if(e.id[1] == 'R')AR++;
}
else if(e.id[0] == 'B'){
if(e.id[1] == 'L')BL++;
else if(e.id[1] == 'R')BR++;
}
if(AL > AR && BL == BR){
ans += rec[i+1].val - e.val;
}
}
cout<< ans <<endl;
}
return 0;
}