# 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();
}
```