#include <iostream> #include <vector> #include <array> constexpr int maxn = 5e5 + 7, treeSize = 1 << 21, mod = 1e9 + 7; int n; std::pair<int, int> polki[maxn], gdzieSpada[maxn]; int ileNaMnieSpada[maxn]; int tree[treeSize]; long long presses; std::array<long long, maxn> fact, oneOverFact; void preprocessFact() { //constexpr std::pair<std::array<long long, maxn>, std::array<long long, maxn>> preprocessFact() { // std::array<long long, maxn> fact = {0}, oneOverFact = {0}; fact[0] = fact[1] = 1; oneOverFact[0] = oneOverFact[1] = 1; for(int i = 2; i <= n; i++) { // for(int i = 2; i <= maxn; i++) { fact[i] = fact[i - 1] * i % mod; long long toMult = fact[i]; oneOverFact[i] = 1; int exp = mod - 2; while(exp) { if(exp & 1) oneOverFact[i] = (oneOverFact[i] * toMult) % mod; toMult = (toMult * toMult) % mod; exp >>= 1; } } // return {fact, oneOverFact}; } long long newton(int a, int k) { return (fact[a] * oneOverFact[k] % mod) * oneOverFact[n - k] % mod; } void add(int l, int r, int x) { l += treeSize / 2; r += treeSize / 2; tree[l] = x; tree[r] = x; while(l / 2 != r / 2) { if(l % 2 == 0) tree[l + 1] = x; if(r % 2 == 1) tree[r - 1] = x; l /= 2; r /= 2; } } int max(int i) { i += treeSize / 2; int ans = tree[i]; while(i) { ans = std::max(ans, tree[i]); i /= 2; } return ans; } void input() { scanf("%d", &n); int a, b; for(int i = 0; i < n; i++) { scanf("%d%d", &a, &b); polki[i] = {a, b}; } } void calcGdzieSpada() { for(int i = 0; i < n; i++) { gdzieSpada[i].first = max(polki[i].first) - 1; gdzieSpada[i].second = max(polki[i].second) - 1; add(polki[i].first, polki[i].second, i + 1); } } bool vis[maxn]; void resetVis() { for(int i = 0; i < n; i++) vis[i] = false; } void dfsior(int v) { vis[v] = true; auto [l, r] = gdzieSpada[v]; if(l >= 0 && !vis[l]) { ileNaMnieSpada[l]++; dfsior(l); } if(r >= 0 && !vis[r]) { ileNaMnieSpada[r]++; dfsior(r); } } void calcIleSpada() { for(int i = 0; i < n; i++) { resetVis(); dfsior(i); } } void calcPresses() { for(int v = 0; v < n; v++) { auto &ile = ileNaMnieSpada[v]; presses += (((newton(n, ile + 1) * fact[ile]) % mod) * fact[n - ile - 1]) % mod; } } long long answer() { return presses * oneOverFact[n] % mod; } int main() { // auto xd = preprocessFact(); fact = xd.first; oneOverFact = xd.second; input(); preprocessFact(); calcGdzieSpada(); calcIleSpada(); calcPresses(); printf("%lld", answer()); 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 123 | #include <iostream> #include <vector> #include <array> constexpr int maxn = 5e5 + 7, treeSize = 1 << 21, mod = 1e9 + 7; int n; std::pair<int, int> polki[maxn], gdzieSpada[maxn]; int ileNaMnieSpada[maxn]; int tree[treeSize]; long long presses; std::array<long long, maxn> fact, oneOverFact; void preprocessFact() { //constexpr std::pair<std::array<long long, maxn>, std::array<long long, maxn>> preprocessFact() { // std::array<long long, maxn> fact = {0}, oneOverFact = {0}; fact[0] = fact[1] = 1; oneOverFact[0] = oneOverFact[1] = 1; for(int i = 2; i <= n; i++) { // for(int i = 2; i <= maxn; i++) { fact[i] = fact[i - 1] * i % mod; long long toMult = fact[i]; oneOverFact[i] = 1; int exp = mod - 2; while(exp) { if(exp & 1) oneOverFact[i] = (oneOverFact[i] * toMult) % mod; toMult = (toMult * toMult) % mod; exp >>= 1; } } // return {fact, oneOverFact}; } long long newton(int a, int k) { return (fact[a] * oneOverFact[k] % mod) * oneOverFact[n - k] % mod; } void add(int l, int r, int x) { l += treeSize / 2; r += treeSize / 2; tree[l] = x; tree[r] = x; while(l / 2 != r / 2) { if(l % 2 == 0) tree[l + 1] = x; if(r % 2 == 1) tree[r - 1] = x; l /= 2; r /= 2; } } int max(int i) { i += treeSize / 2; int ans = tree[i]; while(i) { ans = std::max(ans, tree[i]); i /= 2; } return ans; } void input() { scanf("%d", &n); int a, b; for(int i = 0; i < n; i++) { scanf("%d%d", &a, &b); polki[i] = {a, b}; } } void calcGdzieSpada() { for(int i = 0; i < n; i++) { gdzieSpada[i].first = max(polki[i].first) - 1; gdzieSpada[i].second = max(polki[i].second) - 1; add(polki[i].first, polki[i].second, i + 1); } } bool vis[maxn]; void resetVis() { for(int i = 0; i < n; i++) vis[i] = false; } void dfsior(int v) { vis[v] = true; auto [l, r] = gdzieSpada[v]; if(l >= 0 && !vis[l]) { ileNaMnieSpada[l]++; dfsior(l); } if(r >= 0 && !vis[r]) { ileNaMnieSpada[r]++; dfsior(r); } } void calcIleSpada() { for(int i = 0; i < n; i++) { resetVis(); dfsior(i); } } void calcPresses() { for(int v = 0; v < n; v++) { auto &ile = ileNaMnieSpada[v]; presses += (((newton(n, ile + 1) * fact[ile]) % mod) * fact[n - ile - 1]) % mod; } } long long answer() { return presses * oneOverFact[n] % mod; } int main() { // auto xd = preprocessFact(); fact = xd.first; oneOverFact = xd.second; input(); preprocessFact(); calcGdzieSpada(); calcIleSpada(); calcPresses(); printf("%lld", answer()); return 0; } |