点此看题面

大致题意: 让你把\(n\)个数分成两部分,使得在两部分异或和之和最大的前提下,两个异或和中较小的那个尽量小。输出最优的较小异或和。

线性基

关于线性基,可以看一下这篇博客:线性基入门

解题思路

首先,做这题要有一定的位运算常识。

我们求出所有数的异或和,记作\(s\)。

则对于\(s\)二进制下每一位,我们进行分类讨论:

  • 如果这一位是\(1\)。则划分出的两个集合的异或和这一位必然分别是\(0\)或\(1\),即:两个集合中这一位之和是固定不变的。
  • 如果这一位是\(0\)。则划分出的两个集合的异或和这一位必然是全\(0\)或全\(1\)。

既然我们要让总和最大,由于\(1\)位上的总和不变,则显然应该先去考虑\(0\)位,使\(0\)位尽量为两个\(1\)。

然后,借助线性基的思想,我们修改一下线性基的操作方式,就可以轻松求解此题啦。

对于插入

对于插入,由于我们刚刚已经总结出使\(0\)位尽量为两个\(1\),因此,我们在插入时要优先考虑\(0\)位

具体实现时,就是先对\(0\)位从高到低扫一遍判断是否可以插入,然后对\(1\)位从高到低扫一遍判断是否可以插入。

先扫\(0\)我们就相当于把每个最后插入到\(1\)位的数的\(0\)位全变成了\(0\),使得操作\(1\)位不会影响到\(0\)位,为后面的询问奠定了基础。

对于询问

我们先从高到低扫一遍\(0\)位,如果当前\(ans\)这一位上是\(0\),则我们尽量使其为\(1\)。

由于这一位上的数要么二进制下这一位是\(1\)(可以把\(ans\)这一位上变成\(1\)),要么这个数就是\(0\)(异或\(0\)没有任何影响),因此直接将\(ans\)异或上当前这一位的数即可。

然后从高到低扫一遍\(1\)位,如果\(ans\)这一位是\(1\),由于我们要让这个数尽量小,就异或上当前这一位的数即可(理由同上)。

代码

#include<bits/stdc++.h>
#define Tp template<typename Ty>
#define Ts template<typename Ty,typename... Ar>
#define Reg register
#define RI Reg int
#define RL Reg LL
#define Con const
#define CI Con int&
#define CL Con LL&
#define I inline
#define W while
#define N 100000
#define LL long long
using namespace std;
int n;LL s,a[N+5];
class FastIO
{
private:
#define FS 10000
#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
#define tn (x<<3)+(x<<1)
#define D isdigit(c=tc())
char c,*A,*B,FI[FS];
public:
I FastIO() {A=B=FI;}
Tp I void read(Ty& x) {x=0;W(!D);W(x=tn+(c&15),D);}
Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
}F;
class LinearBasis//线性基
{
private:
#define P 60
LL v[P+5];
public:
#define ins() {if(!v[i]) return (void)(v[i]=x);x^=v[i];}
I void Insert(RL x)
{
RI i;for(i=P;~i;--i) if(!(s>>i&1)&&x>>i&1) ins();//优先考虑0位
for(i=P;~i;--i) if(s>>i&1&&x>>i&1) ins();
}
I LL Query()
{
RI i;RL ans=0;for(i=P;~i;--i) !(s>>i&1)&&!(ans>>i&1)&&(ans^=v[i]);//尽量使0位变成1
for(i=P;~i;--i) s>>i&1&&ans>>i&1&&(ans^=v[i]);return ans;//尽量使1位更小
}
}B;
int main()
{
RI i;for(F.read(n),i=1;i<=n;++i) F.read(a[i]),s^=a[i];//统计所有数异或和
for(i=1;i<=n;++i) B.Insert(a[i]);return printf("%lld",B.Query()),0;//求解并输出答案
}

【LOJ6060】「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set(线性基)的更多相关文章

  1. LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set(线性基,贪心)

    LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set $ solution: $ 这一题的重点在于优先级问题,我们应该先保证总和最大,然后再保证某一个最小.于是我 ...

  2. Loj #6069. 「2017 山东一轮集训 Day4」塔

    Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...

  3. Loj #6073.「2017 山东一轮集训 Day5」距离

    Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...

  4. Loj 6068. 「2017 山东一轮集训 Day4」棋盘

    Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...

  5. 「2017 山东一轮集训 Day5」苹果树

    「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...

  6. 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)

    [LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...

  7. loj6068. 「2017 山东一轮集训 Day4」棋盘 二分图,网络流

    loj6068. 「2017 山东一轮集训 Day4」棋盘 链接 https://loj.ac/problem/6068 思路 上来没头绪,后来套算法,套了个网络流 经典二分图 左边横,右边列 先重新 ...

  8. LOJ #6074. 「2017 山东一轮集训 Day6」子序列

    #6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...

  9. 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP

    [LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...

  10. loj #6077. 「2017 山东一轮集训 Day7」逆序对

    #6077. 「2017 山东一轮集训 Day7」逆序对   题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...

随机推荐

  1. Vue PDF文件预览vue-pdf

       最近做项目,遇到预览PDF这个功能,在网上找了找,大多推荐的是pdf.js,不过在Vue中还是想偷懒直接npm组件,最后找到了一个还不错的Vue-pdf 组件,GitHub地址:https:// ...

  2. k8s 集群搭建

    一,环境介绍   master node1 node2 IP 192.168.0.164 192.168.0.165 192.168.0.167 环境 centos 7 centos 7 centos ...

  3. (转)Linux 最大进程数

    Linux 最大进程数  原文:https://www.cnblogs.com/pangguoping/p/5792075.html 前言 使用环境:centos 7系统 一.查看用户打开的最大进程数 ...

  4. 水平垂直居中方案与flexbox布局

    [前端攻略]最全面的水平垂直居中方案与flexbox布局   最近又遇到许多垂直居中的问题,这是Css布局当中十分常见的一个问题,诸如定长定宽或不定长宽的各类容器的垂直居中,其实都有很多种解决方案.而 ...

  5. Unity3D游戏轻量级xlua热修复框架

    Unity3D游戏轻量级xlua热修复框架   一 这是什么东西 前阵子刚刚集成xlua到项目,目的只有一个:对线上游戏C#逻辑有Bug的地方执行修复,通过考察xlua和tolua,最终选择了xlua ...

  6. 【密码学】RSA算法原理

    RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密. RSA的算法涉及三个参数,n.e1.e2. 其中,n是两个大质数p.q的积,n的二进制 ...

  7. iis6、iis7、apache设置mime类型

    1.IIS6添加方法. 打开iis,展开网站,右键要设置的站点--属性.找到“http头”选项卡--mime类型 进行设置添加. 截图以.ipa mime类型举例. 2.IIS7(iis7.5.iis ...

  8. 04.Path类的学习

    path 是路径的意思. path类是一个静态类,所以path是一个工具类. Path类是专门用来操作路径的. Path的常用方法: namespace _15.Path类的学习 { class Pr ...

  9. C# ObjectArx cad二次开发

    1 环境搭建:安装CAD 和objectArx库,这里安装的是cad2012和objectArx2010 ,vs是2010 2 新建一个类库项目,引用objectArx安装目录下inc文件夹下的AcD ...

  10. 元类(metaclass)

    一.储备知识exec 储备知识exec:有下面三个参数 参数一:字符串形式的命令 参数二:全局作用域(字典形式),如果不指定默认使用globals() 参数三:局部作用域(字典形式),如果不指定默认就 ...