#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; } |
English