hdu 3949 XOR (线性基)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3949

题意:

给出n个数,从中任意取几个数字异或,求第k小的异或和

思路:

线性基求第k小异或和,因为题目中可以出现异或和为0的情况,但线性基里是不会出现异或和为0的情况,所以我们需要多处理下,将数字全插入到线性基中,如果无法插入也就代表会出现异或和为0的情况,那么求第k小就应该变成求线性基中第k-1小。

实现代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M = 1e6+10;
struct Linear_Basis{
    ll b[63],nb[63],tot;
    bool flag = 0;
    void init(){
        flag = 0; tot = 0;
        memset(b,-1,sizeof(b));
        memset(nb,0,sizeof(nb));
    }

    void Insert(ll x){
        for(int i = 62;i >= 0;i --){
            if(x&(1LL<<i)){
                if(b[i] == -1){
                    b[i] = x;
                    return ;
                }
                x ^= b[i];
            }
        }
        flag = 1;
        return ;
    }

    ll Max(ll x){
        ll ret = x;
        for(int i = 62;i >= 0;i --)
            ret = max(ret,ret^b[i]);
        return ret;
    }

    ll Min(ll x){
        ll ret = x;
        for(int i = 0;i <= 62;i ++)
            if(b[i]) ret ^= b[i];
        return ret;
    }

    void rebuild(){
        for(int i = 62;i >= 0;i --){
            if(b[i] == -1) continue;
            for(int j = i-1;j >= 0;j --){
                if(b[j] == -1) continue;
                if(b[i]&(1LL<<j)) b[i]^=b[j];
            }
        }
        for(int i = 0;i <= 62;i ++)
            if(b[i]!=-1) nb[tot++] = b[i];
    }

    ll K_Min(ll k){
        ll res = 0;
        if(flag == 1) k --;
        if(k == 0) return 0;
        if(k >= (1LL<<tot))
            return -1;
        for(int i = 62;i >= 0;i --)
            if(k&(1LL<<i))
                res ^= nb[i];
        return res;
    }
}LB;

int main()
{
    int cas = 1,t,n,m;
    cin>>t;
    while(t--){
        LB.init();
        cin>>n;
        ll x;
        for(int i = 1;i <= n;i ++){
            cin>>x;
            LB.Insert(x);
        }
        LB.rebuild();
        printf("Case #%d:\n",cas++);
        scanf("%d",&m);
        while(m--){
            ll k;
            scanf("%lld",&k);
            printf("%lld\n",LB.K_Min(k));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/kls123/p/9745609.html

时间: 2024-10-07 15:50:06

hdu 3949 XOR (线性基)的相关文章

HDU 3949 XOR(线性基)

题意:给出一组数,求最小的第k个由这些数异或出来的数. 先求这组数的线性基.那么最小的第k个数显然是k的二进制数对应的线性基异或出来的数. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector> # include <queue> # include <stack> # includ

HDU 3949 XOR(高斯消元搞基)

HDU 3949 XOR 题目链接 题意:给定一些数字,问任取几个异或值第k大的 思路:高斯消元搞基,然后从低位外高位去推算 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int N = 10005; int t, n; ll a[N]; void gauss() { int r = 0; for

ACM学习历程—HDU 3949 XOR(xor高斯消元)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 题目大意是给n个数,然后随便取几个数求xor和,求第k小的.(重复不计算) 首先想把所有xor的值都求出来,对于这个规模的n是不可行的. 然后之前有过类似的题,求最大的,有一种方法用到了线性基. 那么线性基能不能表示第k大的呢? 显然,因为线性基可以不重复的表示所有结果.它和原数组是等价的. 对于一个满秩矩阵 100000 010000 001000 000100 000010 000001

BZOJ 2115: [Wc2011] Xor 线性基

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2115 解法: 膜:http://www.cnblogs.com/ljh2000-jump/p/5869925.html 这道题要求从1到n的最大xor和路径,存在重边,允许经过重复点.重复边.那么在图上作图尝试之后就会发现,路径一定是由许多的环和一条从1到n的路径组成.容易发现,来回走是没有任何意义的,因为来回走意味着抵消.考虑这道题求得是路径xor和最大,所以必然我们要想办法处理环的情

HDU 3949: XOR

XOR Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2587    Accepted Submission(s): 877 Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base number A

HDU 3949 XOR 高斯消元

题目大意:给定一个数组,求这些数组通过异或能得到的数中的第k小是多少 首先高斯消元求出线性基,然后将k按照二进制拆分即可 注意当高斯消元结束后若末尾有0则第1小是0 特判一下然后k-- 然后HDU输出long long是用%I64d 无论C艹还是G艹都是 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 10100 using namespa

【BZOJ-2115】Xor 线性基 + DFS

2115: [Wc2011] Xor Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 2142  Solved: 893[Submit][Status][Discuss] Description Input 第一行包含两个整数N和 M, 表示该无向图中点的数目与边的数目. 接下来M 行描述 M 条边,每行三个整数Si,Ti ,Di,表示 Si 与Ti之间存在 一条权值为 Di的无向边. 图中可能有重边或自环. Output 仅包含一个整数,表示最大

HDU3949 XOR(线性基第k小)

Problem Description XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A XOR B, then for each bit of C, we can get its value by check the digit of corresponding position in A and B. And for each digit,

[hdu3949]XOR(线性基求xor第k小)

题目大意:求xor所有值的第k小,线性基模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; const int MAX_BASE=63; ll base[64],a[10006]