计蒜客 蓝桥杯模拟二 区间合并 打扫教室

 
 
 

一天蒜头君被要求打扫 nn 间连续的教室(编号从 11 到 nn),但是蒜头君打扫教室有点随心,想打扫哪间教室就打扫哪间教室,导致最后自己都不知道是否所有的教室都打扫了。

现在告诉你蒜头君打扫了哪些教室,你能告诉蒜头君他还有多少间教室没有打扫吗?

输入格式

第一行输入两个整数 n,mn,m,分别表示教室的个数和蒜头君打扫教室区间段的个数。

接下来 mm 行,每行有两个整数 l,rl,r,表示蒜头君打扫了 [l,r][l,r] 区间的教室。

输出格式

输出一个整数,表示蒜头君还有多少间教室没有打扫。

数据范围

对于 50\%50% 的数据:1 le n, m le 10^31n,m103。

对于 100\%100% 的数据:1 le n,m le 10^6, 1 le l le r le n1n,m106,1lrn。

样例输入

10 3
1 5
3 7
9 10

样例输出

1

题解:
先将区间进行排序,排序后的区间只有相交和不相交两种。当前右边端点大于后面的左边端点时则两个区间相交,否则不相交
然后用总数减去每个相交区间所含个数得到结果
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define ls (r<<1)
#define rs (r<<1|1)
#define debug(a) cout << #a << " " << a << endl
using namespace std;
typedef long long ll;
const ll maxn = 1e6+10;
const ll mod = 10086;
const double pi = acos(-1.0);
const double eps = 1e-8;
struct node {
    ll le, ri;
};
node a[maxn];
bool cmp( node p, node q ) {
    if( p.le == q.le ) {
        return p.ri < q.ri;
    }
    return p.le < q.le;
}
int main() {
    ll n, m;
    scanf("%lld%lld",&n,&m);
    for( ll i = 0; i < m; i ++ ) {
        scanf("%lld%lld",&a[i].le,&a[i].ri);
    }
    sort(a,a+m,cmp);
    ll le = a[0].le, ri = a[0].ri;
    for( ll i = 1; i < m; i ++ ) {
        if( ri >= a[i].le ) {
            le = min(le,a[i].le);
            ri = max(ri,a[i].ri);
        } else {
            n = n - (ri-le+1);
            le = a[i].le;
            ri = a[i].ri;
        }
    }
    n = n - (ri-le+1);
    printf("%lld
",n);
    return 0;
}

  也可以求前缀和

原文地址:https://www.cnblogs.com/l609929321/p/10548938.html