1 条题解
-
0
题意简述
给定长度为 的数组 ,需要构造长度为 的数组 ,使得
$$a_i \mathbin{\&} a_{i+1} = b_i \quad (1 \le i \le n-1) $$若不存在,输出
-1。逐位分析
按位与的性质:某一位为 当且仅当参与运算的两个数在该位都为 。
因此,若 的第 位为 ,则 和 的第 位必须都是 。
若 的第 位为 ,则 和 的第 位不能同时为 。构造方法
- 初始化 为 。
- 遍历 ,将 和 都按位或上 。这一步将所有必须为 的位设置好。
- 再次遍历 ,检查 是否等于 。
- 若相等,说明所有 位的限制也满足(因为那些位上不会同时为 )。
- 若不等,说明某个必须为 的位被迫变成了 ,此时无解,输出
-1。
正确性说明
- 步骤 2 设置了最少的必要 位,如果这样仍然导致某个 的位在 和 上同时为 ,那么任何其他赋值也不可能满足(因为那些 位是强制要求的)。
- 若检查通过,则构造出的 就是合法的。
时间复杂度 (每一位独立操作可以合并为按位或),总复杂度 ,足够快。
参考代码
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int t; cin >> t; while (t--) { int n; cin >> n; vector<int> b(n - 1); for (int i = 0; i < n - 1; ++i) { cin >> b[i]; } vector<int> a(n, 0); for (int i = 0; i < n - 1; ++i) { a[i] |= b[i]; a[i + 1] |= b[i]; } bool ok = true; for (int i = 0; i < n - 1; ++i) { if ((a[i] & a[i + 1]) != b[i]) { ok = false; break; } } if (!ok) { cout << "-1\n"; } else { for (int i = 0; i < n; ++i) { cout << a[i] << " \n"[i == n - 1]; } } } return 0; }
- 1
信息
- ID
- 6817
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者