思路:
可以構造出0 ~ -1 的充要條件是有x個異或運算線性無關的數在0~-1之間, 原因是k個線性無關可以構造個不同的數。
於是求得儘量大的x對數構造即可, 求得時候可以考慮高斯消元法,就是線性基的構造方法
假設基內的數爲,,…, 新加入數k, 讓k取得儘可能小的數,在線性基中就是不斷異或取小值。
構造數列可以考慮對稱的方式構造,將數看做2進制就類似 0 -> 0 | 1 -> 00 01 | 11 10的方式, 也可以考慮dfs構造。
#include<bits/stdc++.h>
using namespace std;
vector<int> V;
vector<int> B, B1;
void add(int k) {
int t = k;
for (auto v : B) k = min(k, k^v);
if (k > 0) {
B.emplace_back(k);
B1.emplace_back(t);
sort(B.begin(), B.end(), greater<int>());
}
}
void construct(int x) {
V.emplace_back(0);
for (int i = 0; i < x; i++) {
for (int j = (1<<i)-1; j>=0 ; j--) {
V.emplace_back(V[j] ^ B1[i]);
}
}
for (auto k : V) cout << k << " ";
cout << endl;
}
int main() {
ios::sync_with_stdio(false);
int n; cin >> n;
V.resize(n);
for (int i = 0; i < n; i++) cin >> V[i];
sort(V.begin(), V.end());
int x = 0, k=0;
for (int i = 1; i < 22; i++) {
for (; k<V.size() && V[k] < (1 << i); k++) {
add(V[k]);
}
if (B.size() == i) x = i;
}
B.clear();
for (int i = 0; i<V.size()&&V[i] < (1 << x); i++)
add(V[i]);
V.clear();
cout <<x<< endl;
construct(x);
}