#include <iostream> #include <vector> #include <algorithm> #include <array> #include <optional> #include <memory> using Interval = std::pair<unsigned int, unsigned int>; using IntervalsVector = std::vector<Interval>; using IntervalsArray = std::array<IntervalsVector, 3>; struct Result { std::optional<Interval> first_interval; std::optional<Interval> second_interval; Result() : first_interval(std::nullopt), second_interval(std::nullopt) {} explicit Result(const std::optional<Interval> first) : first_interval(first), second_interval(std::nullopt) {} explicit Result(const Interval first) : first_interval(first), second_interval(std::nullopt) {} explicit Result(const Interval first, const Interval second) : first_interval(first), second_interval(second) {} }; inline std::optional<Interval> intersection(const Interval& a, const Interval& b) { auto left = std::max(a.first, b.first); auto right = std::min(a.second, b.second); return left > right ? std::nullopt : std::make_optional(std::make_pair(left, right)); } inline Result difference(const Interval &a, const Interval &b) { auto left1 = a.first; auto right1 = std::min(a.second, b.first - 1); auto left2 = std::max(a.first, b.second + 1); auto right2 = a.second; if (right1 >= left2) return Result(std::make_pair(left1, right2)); if (left1 > right1 && left2 <= right2) return Result(std::make_pair(left2, right2)); if (left1 <= right1 && left2 > right2) return Result(std::make_pair(left1, right1)); return Result(std::make_pair(left1, right1), std::make_pair(left2, right2)); } auto three_intervals(Interval &a, Interval &b, Interval &c) { const auto int_intersection = intersection(a, b); if (!int_intersection.has_value()) return Result(); return difference(int_intersection.value(), c); } inline void add_result_to_vector(const Result &result, IntervalsVector &intervals) { if (result.first_interval.has_value()) intervals.push_back(result.first_interval.value()); if (result.second_interval.has_value()) intervals.push_back(result.second_interval.value()); } std::unique_ptr<IntervalsVector> count_result(IntervalsArray& intervals) { IntervalsVector::size_type i0 = 0u, i1 = 0u, i2 = 0u; IntervalsVector result_vector; while (i0 < intervals[0].size() || i1 < intervals[1].size() || i2 < intervals[2].size()) { if (i0 < intervals[0].size() && i1 < intervals[1].size() && i2 < intervals[2].size()) { add_result_to_vector(three_intervals(intervals[0][i0], intervals[1][i1], intervals[2][i2]), result_vector); if (intervals[0][i0].second <= intervals[1][i1].second && intervals[0][i0].second <= intervals[2][i2].second) i0++; else if (intervals[1][i1].second <= intervals[0][i0].second && intervals[1][i1].second <= intervals[2][i2].second) i1++; else i2++; } else if (i0 < intervals[0].size() && i1 < intervals[1].size() && i2 >= intervals[2].size()) { add_result_to_vector(Result(intersection(intervals[0][i0], intervals[1][i1])), result_vector); if (intervals[0][i0].second <= intervals[1][i1].second && intervals[0][i0].second <= intervals[2][i2].second) i0++; if (intervals[1][i1].second <= intervals[0][i0].second && intervals[1][i1].second <= intervals[2][i2].second) i1++; } else { break; } } return std::make_unique<IntervalsVector>(result_vector); } int main() { unsigned int n, m; std::cin >> n >> m; IntervalsArray intervals_vectors; for (auto i = 0u; i < m; i++) { unsigned int l, r, k; std::cin >> l >> r >> k; intervals_vectors[k - 1].emplace_back(l, r); } for (auto& intervals : intervals_vectors) std::sort(intervals.begin(), intervals.end()); auto result = count_result(intervals_vectors); std::sort(result->begin(), result->end()); auto counter = 0u; auto it = result->begin(); auto current = *(it)++; while (it != result->end()) { if (current.second > it->first) { current.second = std::max(current.second, it->second); } else { counter += (current.second - current.first + 1); current = *(it); } ++it; } std::cout << counter << std::endl; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | #include <iostream> #include <vector> #include <algorithm> #include <array> #include <optional> #include <memory> using Interval = std::pair<unsigned int, unsigned int>; using IntervalsVector = std::vector<Interval>; using IntervalsArray = std::array<IntervalsVector, 3>; struct Result { std::optional<Interval> first_interval; std::optional<Interval> second_interval; Result() : first_interval(std::nullopt), second_interval(std::nullopt) {} explicit Result(const std::optional<Interval> first) : first_interval(first), second_interval(std::nullopt) {} explicit Result(const Interval first) : first_interval(first), second_interval(std::nullopt) {} explicit Result(const Interval first, const Interval second) : first_interval(first), second_interval(second) {} }; inline std::optional<Interval> intersection(const Interval& a, const Interval& b) { auto left = std::max(a.first, b.first); auto right = std::min(a.second, b.second); return left > right ? std::nullopt : std::make_optional(std::make_pair(left, right)); } inline Result difference(const Interval &a, const Interval &b) { auto left1 = a.first; auto right1 = std::min(a.second, b.first - 1); auto left2 = std::max(a.first, b.second + 1); auto right2 = a.second; if (right1 >= left2) return Result(std::make_pair(left1, right2)); if (left1 > right1 && left2 <= right2) return Result(std::make_pair(left2, right2)); if (left1 <= right1 && left2 > right2) return Result(std::make_pair(left1, right1)); return Result(std::make_pair(left1, right1), std::make_pair(left2, right2)); } auto three_intervals(Interval &a, Interval &b, Interval &c) { const auto int_intersection = intersection(a, b); if (!int_intersection.has_value()) return Result(); return difference(int_intersection.value(), c); } inline void add_result_to_vector(const Result &result, IntervalsVector &intervals) { if (result.first_interval.has_value()) intervals.push_back(result.first_interval.value()); if (result.second_interval.has_value()) intervals.push_back(result.second_interval.value()); } std::unique_ptr<IntervalsVector> count_result(IntervalsArray& intervals) { IntervalsVector::size_type i0 = 0u, i1 = 0u, i2 = 0u; IntervalsVector result_vector; while (i0 < intervals[0].size() || i1 < intervals[1].size() || i2 < intervals[2].size()) { if (i0 < intervals[0].size() && i1 < intervals[1].size() && i2 < intervals[2].size()) { add_result_to_vector(three_intervals(intervals[0][i0], intervals[1][i1], intervals[2][i2]), result_vector); if (intervals[0][i0].second <= intervals[1][i1].second && intervals[0][i0].second <= intervals[2][i2].second) i0++; else if (intervals[1][i1].second <= intervals[0][i0].second && intervals[1][i1].second <= intervals[2][i2].second) i1++; else i2++; } else if (i0 < intervals[0].size() && i1 < intervals[1].size() && i2 >= intervals[2].size()) { add_result_to_vector(Result(intersection(intervals[0][i0], intervals[1][i1])), result_vector); if (intervals[0][i0].second <= intervals[1][i1].second && intervals[0][i0].second <= intervals[2][i2].second) i0++; if (intervals[1][i1].second <= intervals[0][i0].second && intervals[1][i1].second <= intervals[2][i2].second) i1++; } else { break; } } return std::make_unique<IntervalsVector>(result_vector); } int main() { unsigned int n, m; std::cin >> n >> m; IntervalsArray intervals_vectors; for (auto i = 0u; i < m; i++) { unsigned int l, r, k; std::cin >> l >> r >> k; intervals_vectors[k - 1].emplace_back(l, r); } for (auto& intervals : intervals_vectors) std::sort(intervals.begin(), intervals.end()); auto result = count_result(intervals_vectors); std::sort(result->begin(), result->end()); auto counter = 0u; auto it = result->begin(); auto current = *(it)++; while (it != result->end()) { if (current.second > it->first) { current.second = std::max(current.second, it->second); } else { counter += (current.second - current.first + 1); current = *(it); } ++it; } std::cout << counter << std::endl; } |