Due to the success of TWICE, JYP Entertainment has earned countless money and emerged as the biggest entertainment firm by market capitalization. Therefore, the boss, JYP, has decided to create a new nation and has appointed you to provide a design diagram.
The new nation consists of $n$ cities and some roads between them. JYP has given some restrictions:
- To guarantee efficiency while avoiding chaos, for any $2$ different cities $A$ and $B$, there is exactly one road between them, and it is one-directional. There are no roads connecting a city to itself.
- The logo of rivaling companies should not appear in the plan, that is, there does not exist $4$ distinct cities $A$,$B$,$C$,$D$ , such that the following configuration occurs.
JYP has given criteria for your diagram. For two cities $A$,$B$, let $dis(A,B)$ be the smallest number of roads you have to go through to get from $A$ to $B$. If it is not possible to walk from $A$ to $B$, $dis(A,B) = 614n$. Then, the efficiency value is defined to be the sum of $dis(A,B)$ for all ordered pairs of distinct cities $(A,B)$.
Note that $dis(A,B)$ doesn’t have to be equal to $dis(B,A)$.
You have drawn a design diagram that satisfies JYP’s restrictions. Find the sum of $dis(A,B)$ over all ordered pairs of cities $(A,B)$ with $A\neq B$.
Note that the input is given in compressed form. But even though it is compressed, you’d better use fast input.Input
The first line contains a single integer $n$ ($4 \le n \le 8000$, $n \equiv 0 \pmod{4}$) — the number of cities.
A binary matrix is encrypted in the following format. Each of $n$ next lines contains $\frac{n}{4}$ one-digit hexadecimal numbers (that is, these numbers can be represented either as digits from $0$ to $9$ or as uppercase Latin letters from $A$ to $F$). Binary representation of each of these numbers denotes next $4$ elements of the matrix in the corresponding row. For example, if the number $B$ is given, then the corresponding elements are $1011$, and if the number is $5$, then the corresponding elements are $0101$.
After you obtain the decrypted binary matrix, the $j$-th character of the $i$-th row is $1$ if the one-directional road between cities $i$ and $j$ is directed from $i$ to $j$, and $0$ otherwise. It is guaranteed that the graph satisfies the restrictions mentioned above.Output
Output one integer, representing the sum of $dis(A,B)$ over all ordered pairs of cities $(A,B)$ with $A\neq B$.Examplesinput
4 7 2 1 4
output
7380
input
8 7F 3F 1F 0C 06 03 11 18
output
88464
Note
The first example corresponds to the matrix:
$\begin{matrix} 0111 \\ 0010 \\ 0001 \\ 0100 \\ \end{matrix}$
Which corresponds to this graph:

$dis(1,2)=dis(1,3)=dis(1,4)=dis(2,3)=dis(3,4)=dis(4,2)=1$
$dis(2,4)=dis(4,3)=dis(3,2)=2$
$dis(2,1)=dis(3,1)=dis(4,1)=2456$
Therefore the answer for the diagram is $7380$.
Solution:
#include <bits/stdc++.h> using namespace std; template <typename A, typename B> string to_string(pair<A, B> p); template <typename A, typename B, typename C> string to_string(tuple<A, B, C> p); template <typename A, typename B, typename C, typename D> string to_string(tuple<A, B, C, D> p); string to_string(const string& s) { return '"' + s + '"'; } string to_string(const char* s) { return to_string((string) s); } string to_string(bool b) { return (b ? "true" : "false"); } string to_string(vector<bool> v) { bool first = true; string res = "{"; for (int i = 0; i < static_cast<int>(v.size()); i++) { if (!first) { res += ", "; } first = false; res += to_string(v[i]); } res += "}"; return res; } template <size_t N> string to_string(bitset<N> v) { string res = ""; for (size_t i = 0; i < N; i++) { res += static_cast<char>('0' + v[i]); } return res; } template <typename A> string to_string(A v) { bool first = true; string res = "{"; for (const auto &x : v) { if (!first) { res += ", "; } first = false; res += to_string(x); } res += "}"; return res; } template <typename A, typename B> string to_string(pair<A, B> p) { return "(" + to_string(p.first) + ", " + to_string(p.second) + ")"; } template <typename A, typename B, typename C> string to_string(tuple<A, B, C> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")"; } template <typename A, typename B, typename C, typename D> string to_string(tuple<A, B, C, D> p) { return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")"; } void debug_out() { cerr << endl; } template <typename Head, typename... Tail> void debug_out(Head H, Tail... T) { cerr << " " << to_string(H); debug_out(T...); } #ifdef LOCAL #define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__) #else #define debug(...) 42 #endif int main() { ios::sync_with_stdio(false); cin.tie(0); int n; cin >> n; vector<vector<bool>> g(n, vector<bool>(n, false)); vector<int> din(n, 0); vector<int> dout(n, 0); for (int i = 0; i < n; i++) { string foo; cin >> foo; for (int j = 0; j < (n >> 2); j++) { char c = foo[j]; int d = (c <= '9' ? (int) (c - '0') : (int) (c - 'A' + 10)); for (int k = 0; k < 4; k++) { if (d & (1 << (3 - k))) { int x = (j << 2) | k; g[i][x] = true; dout[i] += 1; din[x] += 1; } } } } const long long none = 614LL * n; long long ans = 0; vector<bool> alive(n, true); for (int rm = n; rm >= 1; rm--) { bool found = false; for (int i = 0; i < n; i++) { if (alive[i] && dout[i] == rm - 1) { alive[i] = false; ans += (1 + none) * (rm - 1); found = true; break; } } if (!found) { vector<int> all; for (int i = 0; i < n; i++) { if (alive[i]) { all.push_back(i); } } debug(all); assert((int) all.size() == rm); vector<int> used(n, 0); vector<int> seq(1, all[0]); used[seq[0]] += 1; vector<int> add; vector<bool> in_seq(n, false); in_seq[seq[0]] = true; for (int it = 0; it < rm; it++) { assert(it < (int) seq.size()); int v = seq[it]; in_seq[v] = false; add.clear(); for (int j = 0; j < n; j++) { if (v != j && !in_seq[j] && alive[j] && !g[v][j]) { assert(used[j] < 2); used[j] += 1; add.push_back(j); } } sort(add.begin(), add.end(), [&](int i, int j) { return g[j][i]; }); for (int u : add) { seq.push_back(u); in_seq[u] = true; } } seq.resize(rm); reverse(seq.begin(), seq.end()); for (int i = 0; i < rm; i++) { int cc = 0; while (cc < rm - 1) { ans += rm - 1 - cc; cc += dout[seq[(i + cc) % rm]]; } } break; } } cout << ans << '\n'; return 0; }