【线性基】51nod1312 最大异或和&LOJ114 k大异或和
1312 最大异或和
第一行一个整数N,且1<=N<=50
接下来N行每行一个整数S[i],且0<=S[i]<=1,000,000,000,000,000 (10^15)
一个整数,即最后集合可能的最大值SUM。
3
1
2
3
8
题解
处理出来线性基直接求得结果即可
代码
//by 减维
#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define il inline
#define db double
#define rg register
#define mpr make_pair
#define maxn 105
#define eps 1e-8
#define inf (1<<30)
#define pi 3.1415926535897932384626L
using namespace std; inline int read()
{
int ret=;bool fla=;char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-'){fla=;ch=getchar();}
while(ch>=''&&ch<=''){ret=ret*+ch-'';ch=getchar();}
return fla?-ret:ret;
} int n,cnt;
ll mx,ans,a[maxn],b[maxn],p[],bin[]; int main()
{
n=read();
bin[]=;for(int i=;i<=;++i) bin[i]=bin[i-]<<;
for(int i=;i<=n;++i) scanf("%lld",&a[i]),b[i]=a[i];
for(int i=;i<=n;++i)
for(int j=;j>=;--j)
if(a[i]&bin[j])
if(!p[j]){p[j]=a[i];break;}
else a[i]^=p[j];
for(int i=;i>=;--i)
for(int j=i-;j>=;--j)
if(p[i]&bin[j]) p[i]^=p[j];
for(int i=;i>=;--i)
if(p[i])
{
if((mx^p[i])>mx) mx^=p[i];
cnt++;
}
ans+=mx*(n-cnt+);
cnt--;
for(int i=;cnt&&i<=;i++)
if(p[i]) ans+=(mx^p[i]),cnt--;
printf("%lld",ans);
return ;
}
#114. k 大异或和
题目描述
这是一道模板题。
给由 n n n 个数组成的一个可重集 S S S,每次给定一个数 k k k,求一个集合 T⊆S T \subseteq S T⊆S,使得集合 T T T 在 S S S 的所有非空子集的不同的异或和中,其异或和 T1xorT2xor…xorT|T| 是第 k k k 小的。
输入格式
第一行一个数 n n n。
第二行 n n n 个数,表示集合 S S S。
第三行一个数 m m m,表示询问次数。
第四行 m m m 个数,表示每一次询问的 k k k。
输出格式
输出 m m m 行,对应每一次询问的答案,第 k k k 小的异或和。如果集合 S S S 的所有非空子集中,不同的异或和数量不足 k k k,输出 −1 -1 −1。
样例
样例输入
3
1 2 3
5
1 2 3 4 5
样例输出
0
1
2
3
-1
数据范围与提示
1≤n,m≤10^5,0≤Si≤250,0≤Si≤250
题解
要把线性基求出来后再消下元
对于询问,把k二进制拆分再求即可
代码
//by 减维
#include<set>
#include<map>
#include<ctime>
#include<cmath>
#include<queue>
#include<bitset>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define il inline
#define db double
#define rg register
#define mpr make_pair
#define maxn 100005
#define eps 1e-8
#define inf (1<<30)
#define pi 3.1415926535897932384626L
using namespace std; inline int read()
{
int ret=;bool fla=;char ch=getchar();
while((ch<''||ch>'')&&ch!='-')ch=getchar();
if(ch=='-'){fla=;ch=getchar();}
while(ch>=''&&ch<=''){ret=ret*+ch-'';ch=getchar();}
return fla?-ret:ret;
} int n,m,cnt;
ll p[],bin[],a[]; int main()
{
n=read();int pd=;
bin[]=;for(int i=;i<=;++i) bin[i]=bin[i-]<<;
for(int i=;i<=n;++i)
{
ll x;scanf("%lld",&x);
for(int j=;j>=;--j)
if(x&bin[j]){
if(!p[j]){p[j]=x;break;}
x^=p[j];
}
if(!x) pd=;
}
for(int i=;i>=;--i)
for(int j=i-;j>=;--j)
if(bin[j]&p[i]) p[i]^=p[j];
for(int i=;i<=;++i) if(p[i]) a[cnt++]=p[i];
m=read();
ll k;
for(int i=;i<=m;++i)
{
scanf("%lld",&k);k-=pd;
ll ans=;
if(k>bin[cnt]-){puts("-1");continue;}
for(int j=cnt-;j>=;--j)
if(k&bin[j]) ans^=a[j];
printf("%lld\n",ans);
}
return ;
}
【线性基】51nod1312 最大异或和&LOJ114 k大异或和的更多相关文章
- LOJ114 k大异或和
传送门 (vjudge和hdu也有但是我觉得LOJ好看!而且限制少!) 不过本题描述有误,应该是k小. 首先我们需要对线性基进行改造.需要把每一位改造成为,包含最高位的能异或出来的最小的数. 为啥呢? ...
- LOJ.114.K大异或和(线性基)
题目链接 如何求线性基中第K小的异或和?好像不太好做. 如果我们在线性基内部Xor一下,使得从高到低位枚举时,选base[i]一定比不选base[i]大(存在base[i]). 这可以重构一下线性基, ...
- Loj 114 k大异或和
Loj 114 k大异或和 构造线性基时有所变化.试图构造一个线性基,使得从高到低位走,异或上一个非 \(0\) 的数,总能变大. 构造时让任意两个 \(bas\) 上有值的 \(i,j\) ,满足 ...
- [LOJ#114]k 大异或和
[LOJ#114]k 大异或和 试题描述 这是一道模板题. 给由 n 个数组成的一个可重集 S,每次给定一个数 k,求一个集合 T⊆S,使得集合 T 在 S 的所有非空子集的不同的异或和中,其异或和 ...
- LibreOJ #114. k 大异或和
二次联通门 : LibreOJ #114. k 大异或和 /* LibreOJ #114. k 大异或和 WA了很多遍 为什么呢... 一开始读入原数的时候写的是for(;N--;) 而重新构造线性基 ...
- LOJ114 k大(xiao)异或和(线性基)
构造线性基后将其消至对任意位至多只有一个元素该位为1.于是就可以贪心了,将k拆成二进制就好.注意check一下是否能异或出0. #include<iostream> #include< ...
- 【loj114】k大异或和 线性基+特判
题目描述 给由 $n$ 个数组成的一个可重集 $S$ ,每次给定一个数 $k$ ,求一个集合 $T⊆S$ ,使得集合 $T$ 在 $S$ 的所有非空子集的不同的异或和中,其异或和 $T_1 ...
- 第k大异或值
这道题与2018年十二省联考中的异或粽子很相像,可以算作一个简易版: 因为这不需要可持久化: 也就是说求任意两个数异或起来的第k大值: 首先把所有数放进trie里. 然后二分答案,枚举每个数,相应地在 ...
- hdu 3949 第k大异或组合
题意: 给你一些数,其中任选一些数(大于等于一个),那么他们有一个异或和. 求所有这样的异或和的第k小. 我们可以将每一位看成一维,然后就是给我们n个60维的向量,求它们线性组合后得到的向量空间中,第 ...
随机推荐
- C#进阶之全面解析Lambda表达式
引言 在实际的项目中遇到一个问题,我们经常在网上搜索复制粘贴,其中有些代码看着非常的简洁,比如Lambda表达式,但是一直没有去深入了解它的由来,以及具体的使用方法,所以在使用的时候比较模糊,其次,编 ...
- 51nod——1640 天气晴朗的魔法 有边权限制的最大生成树
好好读题嗷:“所以我们要求阵中的魔法链的魔力值最大值尽可能的小,与此同时,魔力值之和要尽可能的大.” 第一条件是生成树的最大边权更小,第二条件是在最大边权的限制下搞一个最大生成树. 至于最大生成树,如 ...
- k8s的ingress资源简述
ingress controller是独立与controller-manager的Ingress的主要作用是可以利用nginx,haproxy,envoy,traefik等负载均衡器来暴露集群内部服务 ...
- php扩展开发-快速上手
系统环境CentOS release 6.5 (Final) PHP版本php-5.6.27 扩展开发需要有php环境及php的源代码,我的PHP安装目录/home/zhangxiaomin/stud ...
- JZOJ 3463. 【NOIP2013模拟联考5】军训
3463. [NOIP2013模拟联考5]军训(training) (Standard IO) Time Limits: 2000 ms Memory Limits: 262144 KB Deta ...
- 科学计算库Numpy——文件读写
读文件 要读取的文件 有分隔符的文件 备注:delimiter分隔符. 有多余行的文件 备注:skiprows去掉几行. 指定列 备注:usecols指定使用哪几列. 写文件 保存后的文件 备注:fm ...
- Python中关于集合的介绍及用法
一.集合的含义及创建方法 集合(set)是一种无序的并且里面存放不同元素的序列. 集合可以使用大括号 { } 或者 set() 函数创建集合,注意:创建一个空集合必须用 set() 而不是 { },因 ...
- HDU - 1973 - Prime Path (BFS)
Prime Path Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- vector函数用法
vector是线性容器,它的元素严格的按照线性序列排序,和动态数组很相似,和数组一样,它的元素存储在一块连续的存储空间中,这也意味着我们不仅可以使用迭代器(iterator)访问元素,还可以使用指针的 ...
- 网络安全巧设置 Win2008 R2 防火墙详解(1)
针对一般中小企业型来说,如果希望对企业网络进行安全管理,不一定非得花高价钱购买专业的防火墙设置,直接借助操作系统本身自带的防火墙功能即可以满足一般企业的应用,今天我们就一起来探究一下Windows S ...