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