結果
| 問題 |
No.2505 matriX cOnstRuction
|
| コンテスト | |
| ユーザー |
emthrm
|
| 提出日時 | 2023-07-28 15:38:08 |
| 言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 2,932 bytes |
| コンパイル時間 | 1,647 ms |
| コンパイル使用メモリ | 106,808 KB |
| 実行使用メモリ | 137,700 KB |
| 最終ジャッジ日時 | 2024-10-11 13:25:23 |
| 合計ジャッジ時間 | 8,519 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 32 WA * 32 |
ソースコード
#include <algorithm>
#include <array>
#include <bit>
#include <cassert>
#include <cstdint>
#include <iostream>
#include <iterator>
#include <utility>
#include <vector>
// <WA> #895662 ベース
// 2R' の計算を間違っている。
template <int D>
int Solve(const std::vector<int>& z, const std::vector<std::vector<int>>& a) {
const int n = a.size(), m = a.front().size();
assert(std::ssize(z) == n + m);
std::vector<int> y(n + m, 0);
for (int i = 1; i < n; ++i) {
y[i] = a[i].front() ^ a.front().front();
}
for (int j = 0; j < m; ++j) {
y[j + n] = a.front()[j];
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
if ((y[i] ^ y[j + n]) != a[i][j]) return -1;
}
}
static constexpr int kNoEdge = -1;
static constexpr std::array<std::pair<int, std::int64_t>, 2> kLeaf{
std::make_pair(kNoEdge, 0), std::make_pair(kNoEdge, 0)};
const int inf = (n + m) * 2 + 1;
std::vector trie{kLeaf};
const auto MakeNode = [&trie]() -> int {
const int index = trie.size();
trie.emplace_back(kLeaf);
return index;
};
const auto Add = [&trie, MakeNode](const int y_i, const int z_i, const int w)
-> void {
int index = 0;
for (int bit = D - 1; bit >= 0; --bit) {
const int edge_label = (y_i ^ z_i) >> bit & 1;
if ((z_i >> bit & 1) == 0) {
if (trie[index][edge_label ^ 1].first == kNoEdge) {
trie[index][edge_label ^ 1].first = MakeNode();
}
trie[index][edge_label ^ 1].second += w;
}
if (trie[index][edge_label].first == kNoEdge) {
trie[index][edge_label].first = MakeNode();
}
index = trie[index][edge_label].first;
}
};
for (int i = 0; i < n + m; ++i) {
if (z[i] == 0) {
Add(y[i], z[i], inf);
} else {
Add(y[i], 0, 1);
Add(y[i], z[i], 1);
Add(y[i], std::bit_ceil(static_cast<unsigned int>(z[i])) - 1, inf);
}
}
std::int64_t ans = inf;
const int node_num = trie.size();
std::vector<std::int64_t> f(node_num, 0);
for (int i = 0; i < node_num; ++i) {
for (const auto& [j, weight] : trie[i]) {
if (j == kNoEdge) {
ans = std::min(ans, f[i]);
} else {
f[j] = f[i] + weight;
}
}
}
return ans < inf ? ans : -1;
}
int main() {
constexpr int kMaxT = 50000, kMaxNM = 50000, kDigits = 30;
int t;
std::cin >> t;
assert(1 <= t && t <= kMaxT);
while (t--) {
int n, m;
std::cin >> n >> m;
assert(1 <= n && 1 <= m && n * m <= kMaxNM);
std::vector<int> z(n + m);
for (int i = 0; i < n + m; ++i) {
std::cin >> z[i];
assert(0 <= z[i] && z[i] < (1 << kDigits));
}
std::vector a(n, std::vector(m, 0));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < m; ++j) {
std::cin >> a[i][j];
assert(0 <= a[i][j] && a[i][j] < (1 << kDigits));
}
}
std::cout << Solve<kDigits>(z, a) << '\n';
}
return 0;
}
emthrm