#include <array> #include <bits/stdc++.h> #include <iostream> #include <vector> using namespace std; struct Node { array<int,2> ind; Node* p; int d; Node(){ d = 1; p = this; } void set_ind(int a, int b){ ind = {a,b}; } Node(int a, int b){ ind = {a,b}; p = this; d = 1; } Node* find(){ while(p->p->ind != p->ind) p = p->find(); return p; } }; void onion(Node* l, Node* r){ l = l->find(); r = r->find(); if(l->d<r->d) l->p = r; else r->p = l; if(l->d==r->d) l->d++; } int x, y; void euklides(int a, int b) { if(b!=0) { euklides(b, a%b); int pom = y; y = x - a/b*y; x = pom; } } int P = 1'000'000'007; int inv(int a){ x=1, y=0; euklides(a, P); return (x%P+P)%P; } int main(){ int n, k; cin>>n>>k; vector<vector<int>> perms(k, vector<int>(n)); for(auto&x:perms) for(auto&y:x) cin>>y, y--; vector<vector<Node>> nodes(n, vector<Node>(n)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) nodes[i][j].set_ind(i, j), nodes[i][j].p = &nodes[i][j]; //for(int i=0;i<n;i++) for(int j=0;j<n;j++) //cout << "parent "<<i<<" "<<j<<" :"<<nodes[i][j].p->ind[0]<<" "<<nodes[i][j].p->ind[1]<<endl; for(auto&perm:perms){ for(int i=0;i<n;i++) for(int j=0;j<n;j++){ if(j==i) continue; //cout << "onion ("<<i<<","<<j<<")+("<<perm[i]<<","<<perm[j]<<")"<<endl; if(perm[i]==i && perm[j]==j) continue; onion(&nodes[i][j], &nodes[perm[i]][perm[j]]); } } vector<vector<array<int, 2>>> count(n, vector<array<int,2>>(n)); for(int i=0;i<n;i++) for(int j=0;j<n;j++){ if(j==i) continue; auto a = nodes[i][j].find()->ind; //cout << "count"<<i<<" "<<j<<endl; //cout <<"find:"<<a[0]<<","<<a[1]<<endl; count[a[0]][a[1]] [i>j] ++; } //for(int i=0;i<n;i++) for(int j=0;j<n;j++) cout << count[i][j][0]<<","; cout <<endl; long sum = 0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(j==i) continue; auto [c1,c2] = count[i][j]; if(c1+c2 == 0) continue; //cout << "sizes:"<<c1<<" "<<c2<<endl; sum += c1*1LL*c2%P*inv(c1+c2)%P; sum %= P; } cout << sum<<endl; }
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 124 125 126 | #include <array> #include <bits/stdc++.h> #include <iostream> #include <vector> using namespace std; struct Node { array<int,2> ind; Node* p; int d; Node(){ d = 1; p = this; } void set_ind(int a, int b){ ind = {a,b}; } Node(int a, int b){ ind = {a,b}; p = this; d = 1; } Node* find(){ while(p->p->ind != p->ind) p = p->find(); return p; } }; void onion(Node* l, Node* r){ l = l->find(); r = r->find(); if(l->d<r->d) l->p = r; else r->p = l; if(l->d==r->d) l->d++; } int x, y; void euklides(int a, int b) { if(b!=0) { euklides(b, a%b); int pom = y; y = x - a/b*y; x = pom; } } int P = 1'000'000'007; int inv(int a){ x=1, y=0; euklides(a, P); return (x%P+P)%P; } int main(){ int n, k; cin>>n>>k; vector<vector<int>> perms(k, vector<int>(n)); for(auto&x:perms) for(auto&y:x) cin>>y, y--; vector<vector<Node>> nodes(n, vector<Node>(n)); for(int i=0;i<n;i++) for(int j=0;j<n;j++) nodes[i][j].set_ind(i, j), nodes[i][j].p = &nodes[i][j]; //for(int i=0;i<n;i++) for(int j=0;j<n;j++) //cout << "parent "<<i<<" "<<j<<" :"<<nodes[i][j].p->ind[0]<<" "<<nodes[i][j].p->ind[1]<<endl; for(auto&perm:perms){ for(int i=0;i<n;i++) for(int j=0;j<n;j++){ if(j==i) continue; //cout << "onion ("<<i<<","<<j<<")+("<<perm[i]<<","<<perm[j]<<")"<<endl; if(perm[i]==i && perm[j]==j) continue; onion(&nodes[i][j], &nodes[perm[i]][perm[j]]); } } vector<vector<array<int, 2>>> count(n, vector<array<int,2>>(n)); for(int i=0;i<n;i++) for(int j=0;j<n;j++){ if(j==i) continue; auto a = nodes[i][j].find()->ind; //cout << "count"<<i<<" "<<j<<endl; //cout <<"find:"<<a[0]<<","<<a[1]<<endl; count[a[0]][a[1]] [i>j] ++; } //for(int i=0;i<n;i++) for(int j=0;j<n;j++) cout << count[i][j][0]<<","; cout <<endl; long sum = 0; for(int i=0;i<n;i++) for(int j=0;j<n;j++) { if(j==i) continue; auto [c1,c2] = count[i][j]; if(c1+c2 == 0) continue; //cout << "sizes:"<<c1<<" "<<c2<<endl; sum += c1*1LL*c2%P*inv(c1+c2)%P; sum %= P; } cout << sum<<endl; } |