给定n个整数,将数分解成01序列,由这n个01序列构成矩阵,这n个数构成线性空间,这就是异或空间

将这个矩阵高斯消元,求出t个主元,那么由着t个主元构成的线性空间里总共有2^t个数

设这t个数分别是a1,a2,a3,a4,...at,每个数代表的主元为二进制上的一位1,显然选a1的情况组成的数,必定比不选a1的情况组成的数要大

比如a1...a5转换成二进制后将主元取出来就是 1 1 1 1 1

那么异或空间中,(为了对应整齐,将第1小的数改为第0小,依次类推)

  最小(0)的数就是 0 0 0 0 0即一个也不取,

  第二(1)小的数就是0 0 0 0 1,即只取a5的情况

  第三(2)小的数就是0 0 0 1 0,即只取a4的情况

  第四(3)小的数就是 0 0 0 1 1,即取a4,a5的情况

显而易见 ,第k大的数对应的取法就是k的二进制表示中为1的位!

那么异或空间中最大数(2^t-1)显然是所有数的异或(把每一位都异或为1的情况),最小数(0)就是一个也不取的情况(0)

那么第k大的数就是将k-1 (把k-1为了方便从最小的数开始算起)进行二进制分解,然后取出对应的ai进行异或即可

但是本题中可能存在最小的数(0)不存在的情况:因为不允许xi ^ xi的情况

所以如果给定的数组a不能异或出0的值,就把k-1再加1即可,反之就用k-1进行二进制分解

如何判断能否异或出0的情况?高斯消元后是否有0行出现,即矩阵的秩小于矩阵的行数

普通的高斯消元复杂度数O(n3),其中一个n是矩阵的秩,一个n是矩阵行数,一个n是列数

那么异或空间的复杂度就是O(63*63*n),一个63为秩,一个63为列数,n为行数

  但实际上复杂度为O(63*n),因为异或运算可以把消元的复杂度从m改为1,即对于每行来说只要异或一次就行了

此外,求异或矩阵的主元时,要把除了主元位的其它位都清零,我自己做的时候由于没有清零主元两侧的位,wa了好多发,最后和网上的一对比

发现必须要清楚主元两侧的位

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define maxn 100005
int t,n,q,rk;
ll k;
ll A[maxn],B[maxn],P[maxn];
void Gauss(int n)
{
memset(P,,sizeof(P));
for (int i=;i<=n;i++)
{
for (int j=;j>=;j--)
{
if ((A[i]>>j)&)
{
if (P[j]) A[i]^=P[j];//把这一列的清了
else {P[j]=A[i]; break;}//这行第j个作为主元,因为到第j位就退出了,所以后面的之后再清零
}
}
} for (int i=;i>=;i--)//把P[i]除了主元位的1之外的位(在主元右侧的1)清了
{
if (!P[i]) continue;
for (int j=i+;j<=;j++)
{
if ((P[j]>>i)&) P[j]^=P[i];
}
} rk=;
for (int j=;j<=;j++) if (P[j]) P[rk++]=P[j];
}
/*void Gauss(){
memset(P,0,sizeof P);
for(int i=1;i<=n;i++)
for(int j=63;j>=0;j--)
if((A[i]>>j) & 1){//判断A[i][j]==1
if(P[j]==0){P[j]=i;break;} //A[i][j]设为主元
else A[i]^=A[P[j]];//用其他主元把A[i][j]变成0
} for(int i=63;i>=0;i--){
if(!A[P[i]])continue;
for(int j=i+1;j<=62;j++)
if((A[P[j]]>>i)&1)A[P[j]]^=A[P[i]];
}
rk=0;
for(int j=0;j<=63;j++)//简化后的矩阵B,B[0]为at
if(A[P[j]])B[rk++]=A[P[j]];
}*/
int main(){
cin>>t;
for(int tt=;tt<=t;tt++){
printf("Case #%d:\n",tt); cin>>n;
for(int i=;i<=n;i++)cin>>A[i];
Gauss(n);//预处理构建矩阵
cin>>q;
while(q--){
cin>>k;
if(n!=rk)k--;//不能异或出0
if(k>=(1ll<<rk))puts("-1");
else {
ll ans=;
for(int j=;j<=;j++)//测试k的二进制位
if((k>>j)&)
ans^=P[j];
cout<<ans<<endl;
}
}
}
}

hdu3949 异或空间 + 求矩阵的主元的更多相关文章

  1. 异或空间求基(模板)——hdu3949

    输出样例有点问题的.. #include<bits/stdc++.h> using namespace std; #define ll unsigned long long #define ...

  2. PTA实验7-2-3 求矩阵的局部极大值 (15分)

    实验7-2-3 求矩阵的局部极大值 (15分) 给定M行N列的整数矩阵A,如果A的非边界元素A[i][j]大于相邻的上下左右4个元素,那么就称元素A[i][j]是矩阵的局部极大值.本题要求给定矩阵的全 ...

  3. POJ 1151 Atlantis(经典的线段树扫描线,求矩阵面积并)

    求矩阵的面积并 采用的是区间更新 #include <iostream> #include <stdio.h> #include <string.h> #inclu ...

  4. HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)

    做这道题之前,建议先做POJ 1151  Atlantis,经典的扫描线求矩阵的面积并 参考连接: http://www.cnblogs.com/scau20110726/archive/2013/0 ...

  5. MATLAB中求矩阵非零元的坐标

    MATLAB中求矩阵非零元的坐标: 方法1: index=find(a); [i,j]=ind2sub(size(a),index); disp([i,j]) 方法2: [i,j]=find(a> ...

  6. POJ 1151 Atlantis 求矩阵面积并 扫描线 具体解释

    题意: 给定n个矩阵的左下角和右上角坐标,求矩阵面积并(矩阵总是正放的,即与x轴y轴都平行) 思路: 扫描线裸题 http://www.cnblogs.com/fenshen371/p/3214092 ...

  7. 求矩阵中各列数字的和 Exercise08_01

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年12月 * 题目:求矩阵中各列数字的和 * */ public class Exercise ...

  8. 求矩阵主对角线元素的和 Exercise08_02

    import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年12月 * 题目:求矩阵主对角线元素的和 * */ public class Exercis ...

  9. matlab求矩阵、向量的模

    求矩阵的模: function count = juZhenDeMo(a,b) [r,c] = size(a);%求a的行列 [r1,c1] = size(b);%求b的行列 count = 0; f ...

随机推荐

  1. ssm框架所需jar包整理及各jar包的作用

    以下是我目前新搭建的ssm项目的pom.xml 之后如果需要其他的话再加 <?xml version="1.0" encoding="UTF-8"?> ...

  2. MySql 在cmd下的学习笔记 —— 有关储存过程的操作(procedure)

    我们把若干条sql封装取来,起个名字------把此过程存储在数据库中叫存储过程 调用procedure 储存过程是可以变成的,意味着可以使用变量,表达式,控制结构 来完成复杂的功能 声明变量 pro ...

  3. openstack Q版部署-----环境搭建(1)

    浏览器建议全程使用火狐或者谷歌,不然VNC可能会有问题 一.环境准备 系统:centos7.2 x86_64 controller 2c+8g+40g 10.1.80.110 可以nat上网 comp ...

  4. 3D中的旋转变换

    相比 2D 中的旋转变换,3D 中的旋转变换复杂了很多.关于 2D 空间的旋转,可以看这篇文章.本文主要粗略地探讨一下 3D 空间中的旋转. 旋转的要素 所谓旋转要素就是说,我们只有知道了这些条件,才 ...

  5. HDOJ 3308 LCIS (线段树)

    题目: Problem Description Given n integers.You have two operations:U A B: replace the Ath number by B. ...

  6. FAT32文件格式示例解析

    1.前言 本文主要以一个示例来分析FAT32文件系统的格式,对FAT32文件系统的各个区域详细分析. 2.FAT32文件系统典型分区 3.FAT32文件系统示例 按如下步骤在ubuntu下创建FAT3 ...

  7. 不允许lseek文件 | nonseekable_open()【转】

    转自:https://blog.csdn.net/gongmin856/article/details/8273545 使用数据区时,可以使用 lseek 来往上往下地定位数据.但像串口或键盘一类设备 ...

  8. Centos6.8上httpd配置腾讯云SSL证书

    (1)先按装mod_ssl yum -y install mod_ssl /etc/httpd/conf.d/下会有一个ssl.conf的文件,打开 a)检测本地证书配置是否正确 主要是看下证书及密钥 ...

  9. javascript动态的改变checkbox的选中状态

    <td> <div class="checkbox"> <label> <input type="checkbox" ...

  10. 【转】Linux中profile、bashrc、bash_profile之间的区别和联系

    /etc/profile:此文件为系统的每个用户设置环境信息,当用户第一次登陆时,该文件被执行.并从/etc/profile.d目录的配置文件中搜集shell的设置. 英文描述为: # /etc/pr ...