/*
* Copyright (C) 2020 Paweł Widera
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details:
* http://www.gnu.org/licenses/gpl.html
*/
#include <iostream>
#include <numeric>
#include <array>
#include <vector>
#include <algorithm>
using namespace std;
enum class EType { start, end };
struct Event {
int x;
int dye;
EType type;
int operator<(const Event& other) const {
if (x == other.x) {
return type < other.type;
} else {
return x < other.x;
}
}
bool operator==(const Event& other) const {
return x == other.x && dye == other.dye && type == other.type;
}
};
bool is_green(array<int, 3>& c) {
return c[0] > 0 && c[1] > 0 && c[2] == 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
int first, last, dye;
vector<Event> events;
cin >> n >> m;
events.reserve(2 * m);
for (int i = 0; i < m; ++i) {
cin >> first >> last >> dye;
--dye;
events.push_back({first, dye, EType::start});
events.push_back({last, dye, EType::end});
}
stable_sort(events.begin(), events.end());
int count = 0;
int previous = 1;
bool prev_green = false;
Event last_event = {0};
array<int, 3> colour = {0};
for (auto event: events) {
bool new_state = event.x > last_event.x;
bool update = ((new_state && event.type == EType::end)
|| (!new_state && event.type == EType::end && last_event.type == EType::start));
bool special_update = new_state && last_event.type == EType::start;
// update count for the last (skipped) state
if (special_update) {
if (prev_green) {
count += max(0, last_event.x - previous - 1);
}
if (is_green(colour)) {
++count;
}
previous = last_event.x;
}
// remember if previous state (post removal) was green
if (new_state) {
prev_green = is_green(colour);
}
// update count for the current state
if (update) {
if (prev_green) {
count += max(0, event.x - previous - 1);
}
if (is_green(colour)) {
++count;
}
previous = event.x;
}
// mix in a new dye
if (event.type == EType::start) {
++colour[event.dye];
}
// remove a dye
else {
--colour[event.dye];
}
last_event = event;
}
cout << count << endl;
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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 | /* * Copyright (C) 2020 Paweł Widera * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details: * http://www.gnu.org/licenses/gpl.html */ #include <iostream> #include <numeric> #include <array> #include <vector> #include <algorithm> using namespace std; enum class EType { start, end }; struct Event { int x; int dye; EType type; int operator<(const Event& other) const { if (x == other.x) { return type < other.type; } else { return x < other.x; } } bool operator==(const Event& other) const { return x == other.x && dye == other.dye && type == other.type; } }; bool is_green(array<int, 3>& c) { return c[0] > 0 && c[1] > 0 && c[2] == 0; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, m; int first, last, dye; vector<Event> events; cin >> n >> m; events.reserve(2 * m); for (int i = 0; i < m; ++i) { cin >> first >> last >> dye; --dye; events.push_back({first, dye, EType::start}); events.push_back({last, dye, EType::end}); } stable_sort(events.begin(), events.end()); int count = 0; int previous = 1; bool prev_green = false; Event last_event = {0}; array<int, 3> colour = {0}; for (auto event: events) { bool new_state = event.x > last_event.x; bool update = ((new_state && event.type == EType::end) || (!new_state && event.type == EType::end && last_event.type == EType::start)); bool special_update = new_state && last_event.type == EType::start; // update count for the last (skipped) state if (special_update) { if (prev_green) { count += max(0, last_event.x - previous - 1); } if (is_green(colour)) { ++count; } previous = last_event.x; } // remember if previous state (post removal) was green if (new_state) { prev_green = is_green(colour); } // update count for the current state if (update) { if (prev_green) { count += max(0, event.x - previous - 1); } if (is_green(colour)) { ++count; } previous = event.x; } // mix in a new dye if (event.type == EType::start) { ++colour[event.dye]; } // remove a dye else { --colour[event.dye]; } last_event = event; } cout << count << endl; return 0; } |
English