思路:
根据题意,我们可以操纵任意的\((i, j), 1<= i, j <= n\), 进行 \(a_i = a_i | a_j, a_j = a_i \& a_j\) , 这里其实 相当于交换了一下两个序列的0和1,所以我们可以对任意的序列交换0和1.
因此构造最小字典序就很简单了,我们记录一下每一位的1,然后计算一下,将每一位的1放在靠后的序列来构造最小字典序。
类似题型:
CF#840-A Absolute Maximization
这里代码自己写的太烂了,后来看大佬写的,确实不错,放到这里学习一下。
#include <bits/stdc++.h>
using namespace std;
void solve() {
int n; cin >> n;
vector<int> a(n, 0), b(31, 0);
for (int i = 0; i < n; i ++) {
int x; cin >> x;
for (int j = 0; j < 30; j ++) {
b[j] += (x>>j&1);
}
}
for (int i = 0; i < 31; i ++) {
for (int j = n - 1, k = 1; k <= b[i]; k ++, j --) {
a[j] += (1<<i);
}
}
for (int i = 0; i < n; i ++) {
cout << a[i] << " \n"[i == n - 1];
}
}
int main() {
int _;
cin >> _;
while(_ --) {
solve();
}
}