点此看题面

大致题意: 让你把\(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. GreenPlum 大数据平台--介绍

    一,GreenPlum 01,介绍: Greenplum是一种基于PostgreSQL的分布式数据库,其采用shared-nothing架构,主机.操作系统.内存.存储都是自我控制的,不存在共享. 官 ...

  2. python 管理多版本之pyenv

    一, [root@management ~]# pyenv install -listAvailable versions:  3.3.0  3.3.1  3.3.2  3.3.3  3.3.4  3 ...

  3. (转)CentOS6/7 使用saltstack源安装saltstack

    CentOS6/7 使用saltstack源安装saltstack 原文:https://blog.csdn.net/wh211212/article/details/77053708 CentOS ...

  4. 转-------CNN图像相似度匹配 2-channel network

    基于2-channel  network的图片相似度判别 原文地址:http://blog.csdn.net/hjimce/article/details/50098483 作者:hjimce 一.相 ...

  5. log4j 2整理

    # Log4j 2最佳实践 #Log4j的1.x版本已经被广泛使用于很多应用程序中.然而,它这些年的发展已经放缓.它变得越来越难以维护,因为它需要严格遵循很老的Java版本,并在2015年8月寿终正寝 ...

  6. MongoDB的聚合函数 Aggregate

    Aggregate的使用,有利于我们对MongoDB中的集合进行进一步的拆分. 示例: db.collection.aggregate( {$match:{x:1}, {limit:10}, {$gr ...

  7. java File delete()执行失败原因(转)

    java.io.File里的delete操作很实用也很常用,可以用来删除单独的文件和某一目录.但有时候会出现delete失败的情况,出现这种情况的原因一般有以下几种:1.删除时还有其他程序在使用该文件 ...

  8. JS常用的设计模式(3)-——观察者模式

    观察者模式( 又叫发布者-订阅者模式 )应该是最常用的模式之一. 在很多语言里都得到大量应用. 包括我们平时接触的dom事件. 也是js和dom之间实现的一种观察者模式. div.onclick = ...

  9. [转].NET Core之Entity Framework Core 你如何创建 DbContext

    本文转自:http://www.cnblogs.com/tdws/p/5874212.html 本文版权归博客园和作者吴双共同所有,欢迎转载,转载和爬虫请注明博客园蜗牛原文地址 http://www. ...

  10. Android - Rxjava 使用和原理

    用RxJava写的一个Android的小Demo 我所理解的RxJava——上手其实很简单 http://www.jianshu.com/p/5e93c9101dc5