//#pragma GCC optimize("unroll-loops") //#pragma GCC target("popcnt,avx,tune=native") #include <bits/stdc++.h> using namespace std; #define fwd(i, a, n) for (int i = (a); i < (n); i ++) #define rep(i, n) fwd(i, 0, n) #define all(X) begin(X), end(X) #define sz(X) ((int)X.size()) #define st first #define nd second #define pii pair<int, int> #define vi vector<int> #define ll long long #ifdef LOC auto &operator<<(auto &out, pair<auto, auto> a) { return out << "(" << a.st << ", " << a.nd << ")"; } auto &operator<<(auto &out, auto a) { out << "{"; for (auto b : a) out << b << ", "; return out << "}"; } void dump(auto... x) { ((cerr << x << ", "), ...) << '\n'; } #define debug(x...) cerr << __LINE__ << ": [" #x "]: ", dump(x) #else #define debug(...) 0 #endif const long long MOD = 1e9 + 7; const long long K = 30; const long long M = (1<<K) - 1; long long pow(long long a, long long b){ long long res = 1; while(b){ while(!(b&1)){ a = (a * a) % MOD; b>>=1; } res = (res * a) % MOD; b--; } return res; } long long inv(long long a){ return pow(a, MOD-2); } int32_t main() { ios_base::sync_with_stdio(0), cin.tie(0); int n, k; cin>>n>>k; vector<vector<int>> tab(n, vector<int>(k)); rep(i, k){ rep(j, n){ cin>>tab[j][i]; tab[j][i]--; } } int shift = 0; while((1<<shift) < n)shift++; int mask = (1<<shift) - 1; vector<long long> cnt((1<<(2*shift)), 0); vector<bool> vis((1<<(2*shift)), true); rep(i, n){ rep(j, n){ if(i < j){ cnt[(i<<shift) + j] = 1; } if(i > j){ cnt[(i<<shift) + j] = (1<<K); } } } vector<int> q(n*n, 0); int pos = 0; //int current = 0; long long res = 0; rep(i, n){ rep(j, n){ if(i != j){ int v =(i<<shift) + j; if(vis[v]){ vis[v] = false; long long x = cnt[v]; q[pos++] = v; while(pos > 0){ int u = q[--pos]; int a = (u>>shift); int b = u & mask; rep(ind, k){ int w = (tab[a][ind]<<shift) + tab[b][ind]; if(vis[w]){ q[pos++] = w; x += cnt[w]; vis[w] = false; } } } long long c = (x>>K); long long d = x & M; //debug(c, d); res += (((c*d) % MOD) * inv(c + d))%MOD; res %= MOD; } } } } cout<<res<<"\n"; 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 | //#pragma GCC optimize("unroll-loops") //#pragma GCC target("popcnt,avx,tune=native") #include <bits/stdc++.h> using namespace std; #define fwd(i, a, n) for (int i = (a); i < (n); i ++) #define rep(i, n) fwd(i, 0, n) #define all(X) begin(X), end(X) #define sz(X) ((int)X.size()) #define st first #define nd second #define pii pair<int, int> #define vi vector<int> #define ll long long #ifdef LOC auto &operator<<(auto &out, pair<auto, auto> a) { return out << "(" << a.st << ", " << a.nd << ")"; } auto &operator<<(auto &out, auto a) { out << "{"; for (auto b : a) out << b << ", "; return out << "}"; } void dump(auto... x) { ((cerr << x << ", "), ...) << '\n'; } #define debug(x...) cerr << __LINE__ << ": [" #x "]: ", dump(x) #else #define debug(...) 0 #endif const long long MOD = 1e9 + 7; const long long K = 30; const long long M = (1<<K) - 1; long long pow(long long a, long long b){ long long res = 1; while(b){ while(!(b&1)){ a = (a * a) % MOD; b>>=1; } res = (res * a) % MOD; b--; } return res; } long long inv(long long a){ return pow(a, MOD-2); } int32_t main() { ios_base::sync_with_stdio(0), cin.tie(0); int n, k; cin>>n>>k; vector<vector<int>> tab(n, vector<int>(k)); rep(i, k){ rep(j, n){ cin>>tab[j][i]; tab[j][i]--; } } int shift = 0; while((1<<shift) < n)shift++; int mask = (1<<shift) - 1; vector<long long> cnt((1<<(2*shift)), 0); vector<bool> vis((1<<(2*shift)), true); rep(i, n){ rep(j, n){ if(i < j){ cnt[(i<<shift) + j] = 1; } if(i > j){ cnt[(i<<shift) + j] = (1<<K); } } } vector<int> q(n*n, 0); int pos = 0; //int current = 0; long long res = 0; rep(i, n){ rep(j, n){ if(i != j){ int v =(i<<shift) + j; if(vis[v]){ vis[v] = false; long long x = cnt[v]; q[pos++] = v; while(pos > 0){ int u = q[--pos]; int a = (u>>shift); int b = u & mask; rep(ind, k){ int w = (tab[a][ind]<<shift) + tab[b][ind]; if(vis[w]){ q[pos++] = w; x += cnt[w]; vis[w] = false; } } } long long c = (x>>K); long long d = x & M; //debug(c, d); res += (((c*d) % MOD) * inv(c + d))%MOD; res %= MOD; } } } } cout<<res<<"\n"; return 0; } |