#include <bits/stdc++.h> #define ull unsigned long long #define ll long long #define debug if (0) const ll MOD = 1e9 + 7; ll fast_pow(ll a, int p) { if (p == 0) return 1; if (p % 2 == 0) { ll tmp = fast_pow(a, p / 2); return tmp * tmp % MOD; } return a * fast_pow(a, p - 1) % MOD; } ll inv(ll a) { return fast_pow(a, MOD - 2); } const int MAX_N = 5e5; int n; std::vector<std::pair<int, int>> v; std::vector<int> list[MAX_N + 3]; void input() { std::cin >> n; for (int i = 1; i <= n; i++) { int x, y; std::cin >> x >> y; v.push_back({x, y}); } } const int base = 1 << 19; int t[2 * base + 5]; void set(int L, int R, int val) { L += base; R += base; t[L] = std::max(t[L], val); t[R] = std::max(t[R], val); while (L / 2 != R / 2) { if (L % 2 == 0) t[L + 1] = std::max(t[L + 1], val); if (R % 2 == 1) t[R - 1] = std::max(t[R - 1], val); L /= 2; R /= 2; } } int query(int p) { p += base; int res = t[p]; p /= 2; while (p > 0) { res = std::max(res, t[p]); p /= 2; } return res; } void build_graph() { for (int i = 0; i < n; i++) { int l = query(v[i].first); int r = query(v[i].second); if (l > 0) list[i + 1].push_back(l); if (r > 0 && r != l) list[i + 1].push_back(r); set(v[i].first, v[i].second, i + 1); } } int reachable[MAX_N + 3]; ull dp[MAX_N + 3]; void calc_dp(int l) { for (int i = 1; i <= n; i++) dp[i] = 0; int r = std::min(n, l + 62); std::vector<int> q; for (int i = 0; i <= r - l; i++) dp[l + i] = (1ull << i); for (int v = n; v >= 1; v--) { for (auto u : list[v]) dp[u] |= dp[v]; } for (int v = 1; v <= n; v++) reachable[v] += __builtin_popcountll(dp[v]); } int main() { std::ios_base::sync_with_stdio(0); std::cin.tie(NULL); input(); build_graph(); for (int i = 1; i <= n; i += 63) calc_dp(i); ll result = 0; for (int i = 1; i <= n; i++) result = (result + inv((ll)(reachable[i]))) % MOD; std::cout << result << "\n"; }
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 | #include <bits/stdc++.h> #define ull unsigned long long #define ll long long #define debug if (0) const ll MOD = 1e9 + 7; ll fast_pow(ll a, int p) { if (p == 0) return 1; if (p % 2 == 0) { ll tmp = fast_pow(a, p / 2); return tmp * tmp % MOD; } return a * fast_pow(a, p - 1) % MOD; } ll inv(ll a) { return fast_pow(a, MOD - 2); } const int MAX_N = 5e5; int n; std::vector<std::pair<int, int>> v; std::vector<int> list[MAX_N + 3]; void input() { std::cin >> n; for (int i = 1; i <= n; i++) { int x, y; std::cin >> x >> y; v.push_back({x, y}); } } const int base = 1 << 19; int t[2 * base + 5]; void set(int L, int R, int val) { L += base; R += base; t[L] = std::max(t[L], val); t[R] = std::max(t[R], val); while (L / 2 != R / 2) { if (L % 2 == 0) t[L + 1] = std::max(t[L + 1], val); if (R % 2 == 1) t[R - 1] = std::max(t[R - 1], val); L /= 2; R /= 2; } } int query(int p) { p += base; int res = t[p]; p /= 2; while (p > 0) { res = std::max(res, t[p]); p /= 2; } return res; } void build_graph() { for (int i = 0; i < n; i++) { int l = query(v[i].first); int r = query(v[i].second); if (l > 0) list[i + 1].push_back(l); if (r > 0 && r != l) list[i + 1].push_back(r); set(v[i].first, v[i].second, i + 1); } } int reachable[MAX_N + 3]; ull dp[MAX_N + 3]; void calc_dp(int l) { for (int i = 1; i <= n; i++) dp[i] = 0; int r = std::min(n, l + 62); std::vector<int> q; for (int i = 0; i <= r - l; i++) dp[l + i] = (1ull << i); for (int v = n; v >= 1; v--) { for (auto u : list[v]) dp[u] |= dp[v]; } for (int v = 1; v <= n; v++) reachable[v] += __builtin_popcountll(dp[v]); } int main() { std::ios_base::sync_with_stdio(0); std::cin.tie(NULL); input(); build_graph(); for (int i = 1; i <= n; i += 63) calc_dp(i); ll result = 0; for (int i = 1; i <= n; i++) result = (result + inv((ll)(reachable[i]))) % MOD; std::cout << result << "\n"; } |