Yukicoder No.184 たのしい排他的論理和(HARD)
ちょっと好き。
solution
$64$要素のvectorの次元を数える問題。$O(N)$。
集合を用意し、線形独立を保つまま要素を足していく。 結果の集合の要素数、つまり次元$d$に対し$2^d$が答え。 線形独立性の判定は掃き出し法、特に前進消去部分をする。
implementation
#include <iostream>
#include <vector>
#include <algorithm>
#define repeat(i,n) for (int i = 0; (i) < int(n); ++(i))
#define repeat_reverse(i,n) for (int i = (n)-1; (i) >= 0; --(i))
#define whole(f,x,...) ([&](decltype((x)) whole) { return (f)(begin(whole), end(whole), ## __VA_ARGS__); })(x)
using namespace std;
uint64_t bit(int i) { return 1ull << i; }
void add(vector<uint64_t> & xs, uint64_t y) {
for (uint64_t x : xs) {
repeat_reverse (i,64) {
if (not (x & bit(i)) and not (y & bit(i))) continue;
if ((x & bit(i)) and (y & bit(i))) y ^= x;
break;
}
}
if (y) {
xs.push_back(y);
whole(sort, xs);
whole(reverse, xs);
}
}
int main() {
int n; cin >> n;
vector<uint64_t> acc;
repeat (i,n) {
uint64_t a; cin >> a;
add(acc, a);
}
cout << (1ll << acc.size()) << endl;
return 0;
}