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