HDU - 3949 XOR(线性基)

题目链接

题目大意

  求n个数的子序列的最大异或和。

解题思路

  求出n个数的线性基并排序,然后将k二进制异或上线性基中对应的代表元素即可。

代码

const int maxn = 2e5+10;
ll arr[maxn];
vector<ll> b; //b中存的每个二进制位的代表元素
void insert(ll x) { //设x在线性基中(不是原来的数字)二进制表示为1的最高位为y
    for (auto v : b) x = min(x, x^v); //x的二进制位中小于y的二进制位不能和其他代表元素同为1
    for (auto &v : b) v = min(v, v^x); //b中元素的二进制位中第y位的二进制位不能和x同为1
    if (x) b.push_back(x); 
}
int main(void) {
    IOS; int kase = 0;
    int __; cin >> __;
    while(__--) {
        cout << "Case #" << ++kase << ":" << endl;
        int n; cin >> n;
        b.clear();
        for (int i = 1; i<= n; ++i) {
            cin >> arr[i];
            insert(arr[i]);
        }
        sort(b.begin(), b.end());
        int q; cin >> q;
        while(q--) {
            ll k; cin >> k;
            if (b.size()<n) --k;
            if (k+1>1LL<<b.size()) cout << -1 << endl;
            else {
                ll sum = 0;
                for (int i = 0; i<b.size(); ++i) 
                    if (k>>i&1) sum ^= b[i];
                cout << sum << endl;
            }
        }
    }
	return 0;
}
posted @ 2021-05-27 20:49  shuitiangong  阅读(45)  评论(0编辑  收藏  举报