HDU 3949 XOR (线性基第k小)题解

题意:

给出(n)个数,求出子集异或第(k)小的值,不存在输出-1。

思路:

先用线性基存所有的子集,然后对线性基每一位进行消元,保证只有(d[i])(i)位存在1,那么这样变成了一组基线性基,然后按(k)的二进制找地k小。因为线性基不保存0,所以对有0的情况要进行特判。

代码:

#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn = 1000 + 5;
const int INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
struct Liner_Basis{
    ll d[63], nd[63];
    int tot, flag;
    void init(){
        memset(d, 0, sizeof(d));
        memset(nd, 0, sizeof(nd));
        tot = flag = 0;
    }
    bool insert(ll x){
        for(int i = 62; i >= 0; i--){
            if(x & (1LL << i)){
                if(d[i]) x ^= d[i];
                else{
                    d[i] = x;
                    return true;
                }
            }
        }
        flag = 1;
        return false;
    }
    void rebuild(){
        for(int i = 62; i >= 0; i--){
            if(d[i] == 0) continue;
            for(int j = i - 1; j >= 0; j--){
                if(d[i] & (1LL << j)) d[i] ^= d[j];
            }
        }
        for(int i = 0; i <= 62; i++){
            if(d[i]) nd[tot++] = d[i];
        }
    }
    ll kth_min(ll k){
        if(flag) k--;
        if(k == 0) return 0;
        if(k >= (1LL << tot)) return -1;
        ll ret = 0;
        for(int i = 62; i >= 0; i--){
            if(k & (1LL << i)){
                ret ^= nd[i];
            }
        }
        return ret;
    }
}lb;
int main(){
    int T, ca = 1;
    scanf("%d", &T);
    while(T--){
        int n;
        ll x;
        scanf("%d", &n);
        lb.init();
        for(int i = 1; i <= n; i++){
            scanf("%lld", &x);
            lb.insert(x);
        }
        lb.rebuild();
        int q;
        scanf("%d", &q);
        printf("Case #%d:
", ca++);
        while(q--){
            scanf("%lld", &x);
            printf("%lld
", lb.kth_min(x));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/KirinSB/p/11236453.html