AC题解
2026-04-18 13:34:27
发布于:重庆
1阅读
0回复
0点赞
-
操作不会增加任何数的值
按位与的性质决定了:对于任意两个数 x 和 y,x & y ≤ x 且 x & y ≤ y。所以每一次操作只会让数组中的数变小或保持不变,不会变大。 -
最终状态的共同下界
设初始数组所有数的按位与为 S = a₁ & a₂ & … & aₙ。
由于按位与的结合律,任何操作后得到的新元素,仍然可以表示为原数组中某些元素的按位与。因此,操作过程中任意一个数在任意时刻,其二进制表示的每一位,都一定是所有原数组数在该位的公共部分。
这意味着无论怎么操作,最终每个数都不可能小于 S(即 S 是所有位上都为 1 的最大公共子集)。所以最终数组的最大值必定 ≥ S。 -
可以达到下界 S
对于 S 中为 0 的某一位,原数组中至少存在一个数在该位为 0。我们可以利用长度为 2 的区间操作,将这个 0 逐步“扩散”到整个数组:
假设 a[k] 在该位为 0。我们依次选择区间 [k-1, k]、[k-2, k-1]、…… 将 0 向左传播;再选择 [k, k+1]、[k+1, k+2]、…… 将 0 向右传播。
每个长度为 2 的区间操作会使对称位置的两个数都执行按位与,从而将 0 复制到相邻位置。
最终整个数组所有数在该位都会变成 0。对所有在 S 中为 0 的位都进行这样的传播后,整个数组的每个元素都会等于 S(因为 S 中为 1 的位本来就全是 1,传播 0 不会影响它们)。
此时数组的所有元素都等于 S,最大值为 S,达到了下界。
- 结论
因此,经过若干次操作后,序列最大值的最小可能值恰好等于初始数组中所有数的按位与。对每个测试用例直接输出该值即可。
#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;
int ans;
cin >> ans; // 先读入第一个数
for (int i = 1; i < n; i++) {
int x;
cin >> x;
ans &= x; // 逐个按位与
}
cout << ans << '\n';
}
return 0;
}
这里空空如也







有帮助,赞一个