#include <cstdio> #include <cstdlib> #include <cstdint> #include <numeric> #include <vector> #include <set> using permutation_t = std::vector<int>; static const uint64_t MODULUS = 1000 * 1000 * 1000 + 7; uint64_t count_inversions(const permutation_t& p) { uint64_t total = 0; for (int i = 0; i < p.size(); i++) { for (int j = i + 1; j < p.size(); j++) { if (p[i] > p[j]) { ++total; } } } return total; } permutation_t compose_perms(const permutation_t& a, const permutation_t& b) { permutation_t ret; ret.reserve(a.size()); for (int i = 0; i < a.size(); i++) { ret.push_back(a[b[i]]); } return ret; } uint64_t modular_inverse(int64_t a, int64_t b) { int64_t oldr = a; int64_t r = b; 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 + b) % b; } // printf("modular inverse: %lld\n", olds); return olds; } int main() { // Read data int n, k; scanf("%d %d", &n, &k); std::vector<permutation_t > generators; generators.reserve(n); for (int i = 0; i < k; i++) { permutation_t p; p.reserve(k); for (int j = 0; j < n; j++) { int x; scanf("%d", &x); p.push_back(x - 1); } generators.push_back(std::move(p)); } // Generate all permutations from the elements using permutation_set_t = std::set<permutation_t>; permutation_set_t allperms; permutation_t identity(n); std::iota(identity.begin(), identity.end(), 0); allperms.insert(std::move(identity)); std::vector<permutation_set_t::iterator> hot_items; hot_items.push_back(allperms.begin()); while (!hot_items.empty()) { auto it = hot_items.back(); hot_items.pop_back(); for (const auto& genperm : generators) { auto newp = compose_perms(genperm, *it); auto [newit, inserted] = allperms.emplace(std::move(newp)); if (inserted) { hot_items.push_back(newit); } } } // Count inversions uint64_t inversions = 0; for (const auto& p : allperms) { // for (int i : p) { // printf("%d ", i); // } // printf(": %lld\n", count_inversions(p)); inversions = (inversions + count_inversions(p)) % MODULUS; } inversions = (inversions * modular_inverse(allperms.size(), MODULUS)) % MODULUS; printf("%llu\n", inversions); 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 | #include <cstdio> #include <cstdlib> #include <cstdint> #include <numeric> #include <vector> #include <set> using permutation_t = std::vector<int>; static const uint64_t MODULUS = 1000 * 1000 * 1000 + 7; uint64_t count_inversions(const permutation_t& p) { uint64_t total = 0; for (int i = 0; i < p.size(); i++) { for (int j = i + 1; j < p.size(); j++) { if (p[i] > p[j]) { ++total; } } } return total; } permutation_t compose_perms(const permutation_t& a, const permutation_t& b) { permutation_t ret; ret.reserve(a.size()); for (int i = 0; i < a.size(); i++) { ret.push_back(a[b[i]]); } return ret; } uint64_t modular_inverse(int64_t a, int64_t b) { int64_t oldr = a; int64_t r = b; 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 + b) % b; } // printf("modular inverse: %lld\n", olds); return olds; } int main() { // Read data int n, k; scanf("%d %d", &n, &k); std::vector<permutation_t > generators; generators.reserve(n); for (int i = 0; i < k; i++) { permutation_t p; p.reserve(k); for (int j = 0; j < n; j++) { int x; scanf("%d", &x); p.push_back(x - 1); } generators.push_back(std::move(p)); } // Generate all permutations from the elements using permutation_set_t = std::set<permutation_t>; permutation_set_t allperms; permutation_t identity(n); std::iota(identity.begin(), identity.end(), 0); allperms.insert(std::move(identity)); std::vector<permutation_set_t::iterator> hot_items; hot_items.push_back(allperms.begin()); while (!hot_items.empty()) { auto it = hot_items.back(); hot_items.pop_back(); for (const auto& genperm : generators) { auto newp = compose_perms(genperm, *it); auto [newit, inserted] = allperms.emplace(std::move(newp)); if (inserted) { hot_items.push_back(newit); } } } // Count inversions uint64_t inversions = 0; for (const auto& p : allperms) { // for (int i : p) { // printf("%d ", i); // } // printf(": %lld\n", count_inversions(p)); inversions = (inversions + count_inversions(p)) % MODULUS; } inversions = (inversions * modular_inverse(allperms.size(), MODULUS)) % MODULUS; printf("%llu\n", inversions); return 0; } |