#include <cstdio> #include <cstdlib> #include <cstdint> #include <algorithm> #include <vector> #include <map> static const uint64_t MODULUS = 1000 * 1000 * 1000 + 7; struct shelf { int flooded_by = 0; int last_visited_by = 0; int left = 0; int right = 0; }; uint64_t modular_inverse(const int64_t a) { int64_t oldr = a; int64_t r = MODULUS; int64_t olds = 1; int64_t s = 0; while (r != 0) { const int64_t q = oldr / r; const int64_t newr = oldr - q * r; const int64_t news = olds - q * s; oldr = r; olds = s; r = newr; s = news; } return (olds + MODULUS) % MODULUS; } int main() { int n; scanf("%d", &n); std::vector<shelf> shelves(n + 1); std::map<int, int> top_view; top_view.insert({0, 0}); top_view.insert({2 * n + 1, 0}); // Sentinel so that we don't have to check for end() std::vector<int> left_compression_stack, right_compression_stack; for (int i = 1; i <= n; i++) { int l, r; scanf("%d %d", &l, &r); auto& s = shelves[i]; auto it = top_view.upper_bound(l); auto previt = std::prev(it); s.left = previt->second; int prev_shelf = previt->second; for (; it->first < r; it = top_view.erase(it)) { prev_shelf = it->second; } s.right = prev_shelf; // printf("shelf %d; left %d, right %d\n", i, s.left, s.right); top_view.insert({l, i}); top_view.insert({r, prev_shelf}); } // For each faucet, count how many faucets flood it (including ours) for (int i = 1; i <= n; i++) { shelves[i].last_visited_by = i; for (int j = i; j > 0; j--) { if (shelves[j].last_visited_by == i) { shelves[j].flooded_by++; shelves[shelves[j].left].last_visited_by = i; shelves[shelves[j].right].last_visited_by = i; } } } // for (int i = 1; i <= n; i++) { // printf("Shelf %d flooded by %d faucets\n", i, shelves[i].flooded_by); // } uint64_t sum = 0; for (int i = 1; i <= n; i++) { // If a faucet appears in the sequence before any of the faucets that flood its shelf, // then it will be turned on. Count those sequences. sum = (sum + modular_inverse(shelves[i].flooded_by)) % MODULUS; } printf("%llu\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 | #include <cstdio> #include <cstdlib> #include <cstdint> #include <algorithm> #include <vector> #include <map> static const uint64_t MODULUS = 1000 * 1000 * 1000 + 7; struct shelf { int flooded_by = 0; int last_visited_by = 0; int left = 0; int right = 0; }; uint64_t modular_inverse(const int64_t a) { int64_t oldr = a; int64_t r = MODULUS; int64_t olds = 1; int64_t s = 0; while (r != 0) { const int64_t q = oldr / r; const int64_t newr = oldr - q * r; const int64_t news = olds - q * s; oldr = r; olds = s; r = newr; s = news; } return (olds + MODULUS) % MODULUS; } int main() { int n; scanf("%d", &n); std::vector<shelf> shelves(n + 1); std::map<int, int> top_view; top_view.insert({0, 0}); top_view.insert({2 * n + 1, 0}); // Sentinel so that we don't have to check for end() std::vector<int> left_compression_stack, right_compression_stack; for (int i = 1; i <= n; i++) { int l, r; scanf("%d %d", &l, &r); auto& s = shelves[i]; auto it = top_view.upper_bound(l); auto previt = std::prev(it); s.left = previt->second; int prev_shelf = previt->second; for (; it->first < r; it = top_view.erase(it)) { prev_shelf = it->second; } s.right = prev_shelf; // printf("shelf %d; left %d, right %d\n", i, s.left, s.right); top_view.insert({l, i}); top_view.insert({r, prev_shelf}); } // For each faucet, count how many faucets flood it (including ours) for (int i = 1; i <= n; i++) { shelves[i].last_visited_by = i; for (int j = i; j > 0; j--) { if (shelves[j].last_visited_by == i) { shelves[j].flooded_by++; shelves[shelves[j].left].last_visited_by = i; shelves[shelves[j].right].last_visited_by = i; } } } // for (int i = 1; i <= n; i++) { // printf("Shelf %d flooded by %d faucets\n", i, shelves[i].flooded_by); // } uint64_t sum = 0; for (int i = 1; i <= n; i++) { // If a faucet appears in the sequence before any of the faucets that flood its shelf, // then it will be turned on. Count those sequences. sum = (sum + modular_inverse(shelves[i].flooded_by)) % MODULUS; } printf("%llu\n", sum); return 0; } |