---
# System prepended metadata

title: ZeroJudge f855. 線段覆蓋長度 加強版

---

# ZeroJudge f855. 線段覆蓋長度 加強版

[ZeroJudge f855. 線段覆蓋長度 加強版](https://zerojudge.tw/ShowProblem?problemid=f855)

## 題意

同[b966. 第 3 題 線段覆蓋長度](https://zerojudge.tw/ShowProblem?problemid=b966)。
給定數個一維數線上的線段，求這些線段的所覆蓋的長度(所以重複不算)。

## 解法

有三種做法：排序+掃描線、離散化(map)+差分、離散化(sort + unique)+差分

### 離散化(map)+差分

```cpp=
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#include <bits/stdc++.h>

using namespace std;

map<int, int> m;

void solve() {
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        int l, r;
        cin >> l >> r;
        ++m[l], --m[r];
    }
    auto it = m.begin();
    int now = it->second, prev = it->first, ans = 0;
    for (++it; it != m.end(); ++it) {
        if (now) {
            ans += it->first - prev;
        }
        now += it->second;
        prev = it->first;
    }
    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    solve();
}
```

### 離散化(sort + unique)+差分

```cpp=
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#include <bits/stdc++.h>

#define ALL(x) (x).begin(), (x).end()
#define discrete(x) sort(ALL(x)), x.resize(distance((x).begin(), unique(ALL(x))));
#define query(x, i) lower_bound(ALL(x), i) - (x).begin()
#define SZ(x) (int)x.size()

using namespace std;

int line[20050];

void solve() {
    int n;
    cin >> n;
    vector<int> L(n), R(n);
    for (int i = 0; i < n; ++i) {
        cin >> L[i] >> R[i];
    }
    vector<int> vec;
    vec.assign(ALL(L)), vec.insert(vec.end(), ALL(R));
    discrete(vec);
    for (int i = 0; i < n; ++i) {
        ++line[query(vec, L[i])], --line[query(vec, R[i])];
    }
    int ans = 0, now = 0;
    for (int i = 0; i < SZ(vec); ++i) {
        if (now) {
            ans += vec[i] - vec[i - 1];
        }
        now += line[i];
    }
    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    solve();
}
```

### 排序+掃描線

```cpp=
#pragma GCC optimize("O3,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")

#include <bits/stdc++.h>

using namespace std;

void solve() {
    int n;
    cin >> n;
    vector<pair<int, int>> vec(n);
    for (auto &[a, b] : vec) {
        cin >> a >> b;
    }
    sort(vec.begin(), vec.end());
    int ans = 0;
    pair<int, int> unionSet = vec[0];
    for (int i = 1; i < n; ++i) {
        if (vec[i].first > unionSet.second) {
            ans += unionSet.second - unionSet.first;
            unionSet = vec[i];
        } else if (vec[i].second > unionSet.second) {
            unionSet.second = vec[i].second;
        }
    }
    ans += unionSet.second - unionSet.first;
    cout << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    solve();
}
```