結果

問題 No.2505 matriX cOnstRuction
ユーザー suisensuisen
提出日時 2023-07-27 23:59:41
言語 C++17(gcc12)
(gcc 12.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 4,431 bytes
コンパイル時間 922 ms
コンパイル使用メモリ 80,572 KB
実行使用メモリ 53,376 KB
最終ジャッジ日時 2024-10-06 17:50:18
合計ジャッジ時間 5,030 ms
ジャッジサーバーID
(参考情報)
judge1 / judge2
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
other AC * 34 WA * 30
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

// WA
#include <array>
#include <cstdint>
#include <iostream>
#include <vector>
using Value = uint32_t;
using Weight = int64_t;
// nm
constexpr size_t MAX_NM = 50000;
constexpr size_t BIT_NUM = 30;
namespace binary_trie {
// ID
using Node = size_t;
constexpr Node null_node = ~size_t(0);
// Binary Trie
constexpr size_t MAX_NODE_NUM = 3 * (MAX_NM + 1) * BIT_NUM + 1;
// child[0][i] = i
// child[1][i] = i
std::array<std::array<Node, MAX_NODE_NUM>, 2> child{};
// weight[i] = i
std::array<Weight, MAX_NODE_NUM> weight{};
// 使
size_t node_num = 0;
Node create_node() {
const Node new_node = node_num++;
//
child[0][new_node] = child[1][new_node] = null_node;
weight[new_node] = 0;
return new_node;
}
void clear_nodes() {
node_num = 0;
}
}
// @returns floor(log_2(v))
size_t bit_width(Value v) {
size_t x = 0;
while (Value(1) << (x + 1) <= v) ++x;
return x;
}
// @returns true if the k-th bit of v is 1, false otherwise
bool get_bit(Value v, size_t k) {
return (v >> k) & 1;
}
int64_t solve(
const size_t n, const size_t m,
const std::vector<Value>& R,
const std::vector<Value>& C,
const std::vector<std::vector<Value>>& A) {
static constexpr Weight INF = Weight(1) << 30;
for (size_t i = 0; i < n; ++i) for (size_t j = 0; j < m; ++j) {
if (A[0][0] ^ A[0][j] ^ A[i][0] ^ A[i][j]) {
return -1;
}
}
using binary_trie::Node;
using binary_trie::clear_nodes, binary_trie::create_node;
using binary_trie::null_node, binary_trie::child, binary_trie::weight, binary_trie::node_num;
clear_nodes();
const Node root = create_node();
// f(x) += W * [(x ^ Y) > Z] for all x
auto add_weight = [root](const Value Y, const Value Z, const Weight W) {
const Value YZ = Y ^ Z;
Node cur = root;
for (size_t bit = BIT_NUM; bit-- > 0;) {
const bool edge_label = get_bit(YZ, bit);
if (child[edge_label][cur] == null_node) {
child[edge_label][cur] = create_node();
}
Node nxt = child[edge_label][cur];
// Z bit 0 cur nxt W
if (not get_bit(Z, bit)) {
weight[cur] += W;
weight[nxt] -= W;
}
cur = nxt;
}
};
auto add_weights = [add_weight](const Value Y, const Value v) {
if (v > 0) {
add_weight(Y, 0, 1);
add_weight(Y, v + 1, 1);
add_weight(Y, 2 * (1 << bit_width(v)) - 1, INF);
} else {
add_weight(Y, 0, INF);
}
};
for (size_t i = 0; i < n; ++i) {
const Value Y = A[0][0] ^ A[i][0];
add_weights(Y, R[i]);
}
for (size_t j = 0; j < m; ++j) {
const Value Y = A[0][j];
add_weights(Y, C[j]);
}
Weight ans = INF;
// ID < ID ID
for (Node node = 0; node < node_num; ++node) {
for (const bool edge_label : { 0, 1 }) {
const Node child_node = child[edge_label][node];
if (child_node != null_node) {
weight[child_node] += weight[node];
} else {
// null ==> 0 ==>
ans = std::min(ans, weight[node]);
}
}
}
return ans != INF ? ans : -1;
}
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
size_t t;
std::cin >> t;
for (size_t case_id = 0; case_id < t; ++case_id) {
size_t n, m;
std::cin >> n >> m;
std::vector<Value> R(n), C(m);
for (auto&& elm : R) std::cin >> elm;
for (auto&& elm : C) std::cin >> elm;
std::vector A(n, std::vector<Value>(m));
for (auto&& row : A) for (auto&& elm : row) std::cin >> elm;
std::cout << solve(n, m, R, C, A) << '\n';
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0