Advertisement
Guest User

Untitled

a guest
Nov 4th, 2015
483
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.85 KB | None | 0 0
  1. #include <cstdio>
  2. #include <vector>
  3. #include <cassert>
  4.  
  5. using namespace std;
  6.  
  7. typedef vector<int> perm;
  8. typedef long long llong;
  9.  
  10. perm operator *(const perm& a, const perm& b) {
  11.     assert(a.size() == b.size());
  12.     perm c(a.size());
  13.     for (int i = 0; i < a.size(); i++) {
  14.         c[i] = a[b[i]];
  15.     }
  16.     return c;
  17. }
  18.  
  19. perm inv(const perm& a) {
  20.     perm c(a.size());
  21.     for (int i = 0; i < a.size(); i++)
  22.         c[a[i]] = i;
  23.     return c;
  24. }
  25.  
  26. perm identity(int n) {
  27.     perm c(n);
  28.     for (int i = 0; i < n; i++)
  29.         c[i] = i;
  30.     return c;
  31. }
  32.  
  33. void DFS(const perm& cur, const vector<perm>& generators, vector<perm>& sigma) {
  34.     sigma[cur[0]] = cur;
  35.     for (const perm& g : generators) {
  36.         perm y = g * cur;
  37.         if (sigma[y[0]].empty()) {
  38.             DFS(y, generators, sigma);
  39.         }
  40.     }
  41. }
  42.  
  43. void reduceGenerators(vector<perm>& generators) {
  44.     if (generators.empty())
  45.         return;
  46.     int n = generators.front().size();
  47.     int pt = 0;
  48.     for (int i = 0; i < n; i++) {
  49.         vector<int> posByFirst(n, -1);
  50.         for (int j = pt; j < generators.size(); j++) {
  51.             perm& g = generators[j];
  52.             assert(g[i] >= i);
  53.             if (g[i] == i)
  54.                 continue;
  55.             else if (posByFirst[g[i]] == -1) {
  56.                 posByFirst[g[i]] = pt;
  57.                 g.swap(generators[pt]);
  58.                 pt++;
  59.             } else {
  60.                 g = inv(generators[posByFirst[g[i]]]) * g;
  61.             }
  62.         }
  63.     }
  64.     assert(pt <= n * (n - 1) / 2);
  65.     generators.resize(pt);
  66. }
  67.  
  68. llong calc(vector<perm> generators) {
  69.     if (generators.empty())
  70.         return 1ll;
  71.     int n = generators.front().size();
  72.     if (n == 0)
  73.         return 1ll;
  74.  
  75.     vector<perm> sigma(n, perm());
  76.     DFS(identity(n), generators, sigma);
  77.     vector<perm> invSigma(n, perm());
  78.     for (int i = 0; i < n; i++)
  79.         invSigma[i] = inv(sigma[i]);
  80.  
  81.     int nSigma = 0;
  82.  
  83.     vector<perm> newGenerators;
  84.     for (int i = 0; i < n; i++) {
  85.         if (sigma[i].empty())
  86.             continue;
  87.         nSigma++;
  88.         for (const perm& g : generators) {
  89.             perm x = g * sigma[i];
  90.             assert(!invSigma[x[0]].empty());
  91.             newGenerators.emplace_back(invSigma[x[0]] * x);
  92.         }
  93.     }
  94.  
  95.     reduceGenerators(newGenerators);
  96.     for (perm& g : newGenerators) {
  97.         assert(g[0] == 0);
  98.         g.erase(g.begin() + 0);
  99.         for (int& x : g)
  100.             --x;
  101.     }
  102.  
  103.     return nSigma * calc(newGenerators);
  104. }
  105.  
  106.  
  107. int main() {
  108.     int k, n;
  109.     scanf("%d %d", &k, &n);
  110.     vector<perm> generators;
  111.     for (int i = 0; i < k; i++) {
  112.         perm x(n);
  113.         for (int j = 0; j < n; j++)
  114.             scanf("%d", &x[j]), --x[j];
  115.         generators.emplace_back(x);
  116.     }
  117.     llong ans = calc(generators);
  118.     printf("%lld\n", ans);
  119.     return 0;
  120. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement