公式
B - Long Increasing Walk 解説 by evima
The necessary and sufficient condition for an answer to exist is:
- \(K\geq N\) (proof below)
- If \(N\) is odd, \(K\leq N(N-1)+1\) (because the maximum length of an Eulerian path in an \(N\)-vertex graph is \(N(N-1)+1\))
Construction
First, construct the case \(K=N\). This can be achieved by filling diagonally from the smallest value. From there, we can adjust by two diagonals at a time.

(Implementation example)
T = int(input())
for _ in range(T):
N, K = map(int, input().split())
if K < N or (N % 2 == 1 and K > N * (N - 1) + 1):
print("No")
continue
M = K - N
ans = [[-1] * N for i in range(N)]
for i in range(0, N, 2):
if i + 1 == N:
for j in range(N):
ans[(j - 2) % N][j] = i * N + j
continue
row1 = [((i + j) % N, j) for j in range(N - 1, -1, -1)]
row2 = [((i + j) % N, (j + 1) % N) for j in range(N - 1, -1, -1)]
tmp = i * N
for i in range(min(M, 2 * N - 2)):
x, y = row1.pop()
row1, row2 = row2, row1
ans[x][y] = tmp
tmp += 1
for x, y in row1[::-1] + row2[::-1]:
ans[x][y] = tmp
tmp += 1
M -= min(M, 2 * N - 2)
print("Yes")
for row in ans:
print(*[i + 1 for i in row])
Proof that \(K\geq N\)
Consider a judge that receives \(N, A\) and returns the answer to the subproblem.
int judge(int N, vector<vector<int>> A) {
vector<pair<int, int>> order(N * N);
for (int l = 0; l < N; l++) {
for (int r = 0; r < N; r++) {
order[A[l][r] - 1] = {l, r};
}
}
vector<int> dpL(N, 0), dpR(N, 0);
for (int i = 0; i < N * N; i++) {
auto [l, r] = order[i];
int a = dpL[l], b = dpR[r];
dpL[l] = max(a, b + 1);
dpR[r] = max(a + 1, b);
}
return max(*max_element(dpL.begin(), dpL.end()), *max_element(dpR.begin(), dpR.end()));
}
Here, in the for statement at line 10, we can see that for each \((l,r)\), \(\sum \mathrm{dpL} + \sum \mathrm{dpR}\) always increases by at least \(2\). Thus, the final value of \(\sum \mathrm{dpL} + \sum \mathrm{dpR}\) is at least \(2N^2\), so \(\max(\max(\mathrm{dpL}),\max(\mathrm{dpR}))\geq N\).
投稿日時:
最終更新: