#include <algorithm> #include <set> #include <stdio.h> template <typename T> class interval_tree { public: struct interval { T min; T max; bool operator<(const interval &i) const { return min < i.min; } }; void merge(const interval i) { auto it = m_data.lower_bound(i); while (it != m_data.end() && i.min <= it->min && it->max <= i.max) { m_data.erase(it); it = m_data.lower_bound(i); } const auto left = find(i.min - 1); const auto right = find(i.max + 1); const auto left_contains = contains(i.min - 1, left); const auto right_contains = contains(i.max + 1, right); if (left_contains && right_contains) { m_data.erase(left); if (left != right) m_data.erase(right); m_data.insert({left->min, right->max}); } else if (left_contains) { m_data.erase(left); m_data.insert({left->min, i.max}); } else if (right_contains) { m_data.erase(right); m_data.insert({i.min, right->max}); } else { m_data.insert(i); } } bool contains(const T &value) { return contains(value, find(value)); } private: typename std::set<interval>::iterator find(const T value) { auto index = m_data.lower_bound({value, value}); if (index == m_data.end()) { if (index != m_data.begin()) index--; } else if (index->min != value) { if (index != m_data.begin()) index--; } return index; } bool contains(const T value, typename std::set<interval>::iterator index) { return index != m_data.end() && index->min <= value && value <= index->max; } std::set<interval> m_data; }; int main() { interval_tree<int> y, b, r; int n, m, left, right, color; scanf("%d %d", &n, &m); for (int i = 0; i < m; ++i) { scanf("%d %d %d", &left, &right, &color); if (color == 1) y.merge({left, right}); else if (color == 2) b.merge({left, right}); else if (color == 3) r.merge({left, right}); } int sum = 0; for (int i = 1; i <= n; ++i) if (y.contains(i) && b.contains(i) && !r.contains(i)) sum++; printf("%d\n", sum); return 0; }
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 | #include <algorithm> #include <set> #include <stdio.h> template <typename T> class interval_tree { public: struct interval { T min; T max; bool operator<(const interval &i) const { return min < i.min; } }; void merge(const interval i) { auto it = m_data.lower_bound(i); while (it != m_data.end() && i.min <= it->min && it->max <= i.max) { m_data.erase(it); it = m_data.lower_bound(i); } const auto left = find(i.min - 1); const auto right = find(i.max + 1); const auto left_contains = contains(i.min - 1, left); const auto right_contains = contains(i.max + 1, right); if (left_contains && right_contains) { m_data.erase(left); if (left != right) m_data.erase(right); m_data.insert({left->min, right->max}); } else if (left_contains) { m_data.erase(left); m_data.insert({left->min, i.max}); } else if (right_contains) { m_data.erase(right); m_data.insert({i.min, right->max}); } else { m_data.insert(i); } } bool contains(const T &value) { return contains(value, find(value)); } private: typename std::set<interval>::iterator find(const T value) { auto index = m_data.lower_bound({value, value}); if (index == m_data.end()) { if (index != m_data.begin()) index--; } else if (index->min != value) { if (index != m_data.begin()) index--; } return index; } bool contains(const T value, typename std::set<interval>::iterator index) { return index != m_data.end() && index->min <= value && value <= index->max; } std::set<interval> m_data; }; int main() { interval_tree<int> y, b, r; int n, m, left, right, color; scanf("%d %d", &n, &m); for (int i = 0; i < m; ++i) { scanf("%d %d %d", &left, &right, &color); if (color == 1) y.merge({left, right}); else if (color == 2) b.merge({left, right}); else if (color == 3) r.merge({left, right}); } int sum = 0; for (int i = 1; i <= n; ++i) if (y.contains(i) && b.contains(i) && !r.contains(i)) sum++; printf("%d\n", sum); return 0; } |