【HDU 3949】 XOR (线性基,高斯消元)
XOR
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2302 Accepted Submission(s): 783Problem DescriptionXOR 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, 1 XOR 1 = 0, 1 XOR 0 = 1, 0 XOR 1 = 1, 0 XOR 0 = 0. And we simply write this operator as ^, like 3 ^ 1 = 2,4 ^ 3 = 7. XOR is an amazing operator and this is a question about XOR. We can choose several numbers and do XOR operatorion to them one by one, then we get another number. For example, if we choose 2,3 and 4, we can get 2^3^4=5. Now, you are given N numbers, and you can choose some of them(even a single number) to do XOR on them, and you can get many different numbers. Now I want you tell me which number is the K-th smallest number among them.InputFirst line of the input is a single integer T(T<=30), indicates there are T test cases.
For each test case, the first line is an integer N(1<=N<=10000), the number of numbers below. The second line contains N integers (each number is between 1 and 10^18). The third line is a number Q(1<=Q<=10000), the number of queries. The fourth line contains Q numbers(each number is between 1 and 10^18) K1,K2,......KQ.OutputFor each test case,first output Case #C: in a single line,C means the number of the test case which is from 1 to T. Then for each query, you should output a single line contains the Ki-th smallest number in them, if there are less than Ki different numbers, output -1.Sample Input2
2
1 2
4
1 2 3 4
3
1 2 3
5
1 2 3 4 5Sample OutputCase #1:
1
2
3
-1
Case #2:
0
1
2
3
-1HintIf you choose a single number, the result you get is the number you choose.
Using long long instead of int because of the result may exceed 2^31-1.
求线性基?好像很厉害的东西..
证明的话应该要用到X^Y=Z -> X^Z=Y这个性质
线性基的相互异或的值可以完全代替原来的n个数的异或的值,这样数从n个变成了二进制位数个,数减少了很多这是一个优点。
另外,像高斯消元一样求线性基的话,如果某一位上有代表这一位的1,那么其他位置上一定为0。(这个性质好像很好用,因为这样可以看作这个数是对这一位作唯一贡献的,这样求很多东西都很方便了) 所以感觉异或版的高斯消元跟普通的高斯消还是很不一样的,多了好性质啊..
放一下让我看懂的解释吧~
1、线性基:
若干数的线性基是一组数a1,a2,...an,其中ax的最高位的1在第x位。通过线性基中元素xor出的数的值域与原来的数xor出数的值域相同。
2、线性基的构造法:
对每一个数p从高位到低位扫,扫到第x位为1时,若ax不存在,则ax=p并结束此数的扫描,否则令p=p xor ax。
3、查询:
用线性基求这组数xor出的最大值:从高往低扫ax,若异或上ax使答案变大,则异或。
4、判断:
用线性基求一个数能否被xor出:从高到低,对该数每个是1的位置x,将这个数异或上ax(注意异或后这个数为1的位置和原数就不一样了),若最终变为0,则可被异或出。需要特判0(在构造过程中看是否有p变为0即可)。例子:(11111,10001)的线性基是a5=11111,a4=01110,要判断11111能否被xor出,11111 xor a5=0,则这个数后来就没有是1的位置了,最终得到结果为0,说明11111能被xor出。
个人谈一谈对线性基的理解:
很多情况下,只有有关异或运算和求最值,就可以用到线性 基。线性基有很多很好的性质,比如说如果有很多个数,我们可以构出这些数的线性基,那么这个线性基可以通过互相xor,能够构出原来的数可以相互xor构出的所有的数。所以可以大大减少判断的时间和次数。同时线性基的任何一个非空子集都不会使得其xor和为0,证明也很简单,反证法就可以说明。这个性质在很多题目中可以保证算法合法性,比如:BZOJ2460。
构造的方法有点像贪心,从大到小保证高位更大。也比较好理解。就是这几行代码:
for(int i=1;i<=n;i++) {
for(int j=62;j>=0;j--) {
if(!(a[i]>>j)) continue;//对线性基的这一位没有贡献
if(!p[j]) { p[j]=a[i]; break; }//选入线性基中
a[i]^=p[j];
}
}
可以把n个数变成只有二进制位数那么多的数,这就是线性基的优秀之处。
查询的话,也是一个贪心思想,如果可以使得ans更大,就把这一位的基xor进ans。
for(int i=62;i>=0;i--) if((ans^p[i])>ans) ans=ans^p[i];//从线性基中得到最大值
这就是线性基的基本用法和个人的一些理解。
代码如下:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cmath>
using namespace std;
#define Maxn 10010
#define LL long long LL a[Maxn],num[];
int n,cnt; void gauss()
{
int l=,r=;
LL t;
while(l<=n&&r>=)
{
if(!(a[l]&(1LL<<r-)))
{
for(int i=l+;i<=n;i++) if(a[i]&(1LL<<r-))
{
t=a[l],a[l]=a[i],a[i]=t;
break;
}
}
if(!(a[l]&(1LL<<r-)))
{
r--;continue;
}
num[r]=l;
for(int i=;i<=n;i++) if(i!=l&&(a[i]&(1LL<<r-))) a[i]^=a[l];
l++;r--;
}
} void init()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%lld",&a[i]);
memset(num,,sizeof(num));
gauss();
for(int i=;i<=;i++) if(num[i]!=) num[i]=a[num[i]];
cnt=;
for(int i=;i<=;i++) if(num[i]!=) cnt++;
} int main()
{
int T,kase=;
scanf("%d",&T);
while(T--)
{
init();
printf("Case #%d:\n",++kase);
int q;
scanf("%d",&q);
while(q--)
{
LL k;
scanf("%lld",&k);
if(cnt==n) k++;//zero
if(k>(1LL<<cnt)) {printf("-1\n");continue;}
int now=cnt;
LL ans=;
for(int i=;i>=;i--) if(num[i]!=)
{
LL x=(1LL<<now-);
if(k>x) ans^=num[i],k-=x;
now--;
}
printf("%lld\n",ans);
}
}
return ;
}
[HDU3969]
2016-09-30 15:03:05
【HDU 3949】 XOR (线性基,高斯消元)的更多相关文章
- HDU 3949 XOR [线性基|高斯消元]
目录 题目链接 题解 代码 题目链接 HDU 3949 XOR 题解 hdu3949XOR 搞死消元找到一组线性无关组 消出对角矩阵后 对于k二进制拆分 对于每列只有有一个1的,显然可以用k的二进制数 ...
- HDU 3949 XOR ——线形基 高斯消元
[题目分析] 异或空间的K小值. 高斯消元和动态维护线形基两种方法都试了试. 动态维护更好些,也更快(QAQ,我要高斯消元有何用) 高斯消元可以用来开拓视野. 注意0和-1的情况 [代码] 高斯消元 ...
- [bzoj 2844]线性基+高斯消元
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2844 又用到线性基+高斯消元的套路题了,因为经过高斯消元以后的线性基有非常好的序关系,所以 ...
- [hdu 3949]线性基+高斯消元
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3949 一开始给做出来的线性基wa了很久,最后加了一步高斯消元就过了. 之所以可以这样做,证明如下. 首 ...
- Codeforces.472F.Design Tutorial: Change the Goal(构造 线性基 高斯消元)
题目链接 \(Description\) 给定两个长为\(n\)的数组\(x_i,y_i\).每次你可以选定\(i,j\),令\(x_i=x_i\ \mathbb{xor}\ x_j\)(\(i,j\ ...
- 【题解】 bzoj1923: [Sdoi2010]外星千足虫 (线性基/高斯消元)
bzoj1923,戳我戳我 Solution: 这个高斯消元/线性基很好看出来,主要是判断在第K 次统计结束后就可以确定唯一解的地方和\(bitset\)的骚操作 (我用的线性基)判断位置,我们可以每 ...
- 洛谷P3265 [JLOI2015]装备购买(线性基+高斯消元)
传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 不难看出题目讲的就是线性基 这种最小化权值的问题一般都是贪心的,就是按价值从低到高考虑每一个是否能选 据说贪心的证明得用拟阵我不会 据说这题是实数意 ...
- 【bzoj4004】【JLOI2015】装备购买 (线性基+高斯消元)
Description 脸哥最近在玩一款神奇的游戏,这个游戏里有 n 件装备,每件装备有 m 个属性,用向量zi(aj ,.....,am) 表示 (1 <= i <= n; 1 < ...
- hdu 3949 XOR (线性基)
链接: http://acm.hdu.edu.cn/showproblem.php?pid=3949 题意: 给出n个数,从中任意取几个数字异或,求第k小的异或和 思路: 线性基求第k小异或和,因为题 ...
- HDU 3949 XOR 线性基
http://acm.hdu.edu.cn/showproblem.php?pid=3949 求异或第k小,结论是第k小就是 k二进制的第i位为1就把i位的线性基异或上去. 但是这道题和上一道线性基不 ...
随机推荐
- mysql 中间件 分析
360的Atlas 1.读写分离 2.从库负载均衡 3.IP过滤 4.自动分表 5.DBA可平滑上下线DB 6.自动摘除宕机的DB altas 在10000/s的请求量级应该是毫无问题的 https: ...
- IDispose(), Finalize()
C# using 用法: 1. 作为指令,用于为命名空间创建别名或导入其他命名空间中定义的类型.(见例1-1) 2. 作为语句,用于定义一个范围,在此范围的末尾将释放对象.(见例1-2) (例子1- ...
- andorid 平台调用Web Service , 图片传输
今天学习了下android调用web service,进行图片传输 下面是代码详解: onActivityResult 方法在图片剪裁完成之后调用: protected void onActivity ...
- FOR XML PATH 转换问题
以下我带大家了解关于 FOR XML PATH 首先我们看下所熟悉的表数据 之后转换 <骨牌编号>1</骨牌编号> <骨牌颜色>橙</骨牌颜色> < ...
- Android获取屏幕尺寸大小
官方API: A structure describing general information about a display, such as its size, density, and fo ...
- WKWebView详解
WKWebView是在Apple的WWDC 2014随iOS 8和OS X 10.10出来的,是为了解决UIWebView加载速度慢.占用内存大的问题.使用UIWebView加载网页的时候,我们会发现 ...
- 关于tableView的那些坑(一)—— automaticallyAdjustsScrollViewInsets属性
最近用tabbar来切换控制器,用childViewController来实现多控制器管理,多列表切换,在子控制器中设置了automaticallyAdjustsScrollViewInsets属性为 ...
- atc游戏bot
游戏玩起来太虐心了,就写了个bot来玩, 代码在此: git clone https://github.com/chenfengyuan/atc-bot-new.gitgit clone https: ...
- (转)IOS学习笔记-2015-03-29 int、long、long long取值范围
unsigned - - unsigned - - unsigned __int64的最大值: __int64的最小值:- unsigned __int64的最大值:
- spark-shell - 将结果保存成一个文件
sqlContext.sql(""" SELECT user_no,cust_id,oper_code FROM cui.operation_data_an ...