【LOJ6060】「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set(线性基)
大致题意: 让你把\(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(线性基)的更多相关文章
- LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set(线性基,贪心)
LOJ 6060「2017 山东一轮集训 Day1 / SDWC2018 Day1」Set $ solution: $ 这一题的重点在于优先级问题,我们应该先保证总和最大,然后再保证某一个最小.于是我 ...
- Loj #6069. 「2017 山东一轮集训 Day4」塔
Loj #6069. 「2017 山东一轮集训 Day4」塔 题目描述 现在有一条 $ [1, l] $ 的数轴,要在上面造 $ n $ 座塔,每座塔的坐标要两两不同,且为整点. 塔有编号,且每座塔都 ...
- Loj #6073.「2017 山东一轮集训 Day5」距离
Loj #6073.「2017 山东一轮集训 Day5」距离 Description 给定一棵 \(n\) 个点的边带权的树,以及一个排列$ p\(,有\)q $个询问,给定点 \(u, v, k\) ...
- Loj 6068. 「2017 山东一轮集训 Day4」棋盘
Loj 6068. 「2017 山东一轮集训 Day4」棋盘 题目描述 给定一个 $ n \times n $ 的棋盘,棋盘上每个位置要么为空要么为障碍.定义棋盘上两个位置 $ (x, y),(u, ...
- 「2017 山东一轮集训 Day5」苹果树
「2017 山东一轮集训 Day5」苹果树 \(n\leq 40\) 折半搜索+矩阵树定理. 没有想到折半搜索. 首先我们先枚举\(k\)个好点,我们让它们一定没有用的.要满足这个条件就要使它只能和坏 ...
- 【LOJ#6066】「2017 山东一轮集训 Day3」第二题(哈希,二分)
[LOJ#6066]「2017 山东一轮集训 Day3」第二题(哈希,二分) 题面 LOJ 题解 要哈希是很显然的,那么就考虑哈希什么... 要找一个东西可以表示一棵树,所以我们找到了括号序列. 那么 ...
- loj6068. 「2017 山东一轮集训 Day4」棋盘 二分图,网络流
loj6068. 「2017 山东一轮集训 Day4」棋盘 链接 https://loj.ac/problem/6068 思路 上来没头绪,后来套算法,套了个网络流 经典二分图 左边横,右边列 先重新 ...
- LOJ #6074. 「2017 山东一轮集训 Day6」子序列
#6074. 「2017 山东一轮集训 Day6」子序列 链接 分析: 首先设f[i][j]为到第i个点,结尾字符是j的方案数,这个j一定是从i往前走,第一个出现的j,因为这个j可以代替掉前面所有j. ...
- 【LOJ6077】「2017 山东一轮集训 Day7」逆序对 生成函数+组合数+DP
[LOJ6077]「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k ,请求出长度为 n的逆序对数恰好为 k 的排列的个数.答案对 109+7 取模. 对于一个长度为 n 的排列 p ...
- loj #6077. 「2017 山东一轮集训 Day7」逆序对
#6077. 「2017 山东一轮集训 Day7」逆序对 题目描述 给定 n,k n, kn,k,请求出长度为 n nn 的逆序对数恰好为 k kk 的排列的个数.答案对 109+7 10 ^ 9 ...
随机推荐
- SqlSugar ORM框架文档
http://www.codeisbug.com/Doc/8/1141 SqlSugar入门级教程+实例 (.net core下的)https://www.cnblogs.com/rulasann/p ...
- python学习13-类的约束 异常处理 日志
一 .约束 python中约束有两种 第一种,通过抛异常进行约束,这种是子类不按我要求的来,我就给你抛异常(推荐) 操作:提取一个父类. 在父类中给出一个方法.但在方法中不给出任何代码,直接抛异常 # ...
- android检查网络连接状态的变化,无网络时跳转到设置界面
在AndroidManifest.xml中加一个声明<receiver android:name="NetCheckReceiver"> <intent-filt ...
- 分支结构if……else
语法: if(条件) 语句或语句块1 end else begin 语句或者语句块2 end 特点: . else并不一定是必须的. . 如否条件为真,将执行语句和语句块1,条件为假时执行语句或语句块 ...
- SpringSecurity 3.2入门(3)单用户登录
1.增加web.xml文件配置如下 <!-- 获取Spring Security session的生命周期,这个监听器会在 session 创建和销毁的时候通知 Spring Security ...
- C#基础知识-数组_ArrayList_List(九)
之前两篇文档讲述了C#中的面向对象的概念,其实这个概念对于很多种语言都是通用的,只不过每种语言具体实现的过程方法不一样,比如Java.C++.python等,这些都是很流行的面向对象的语言在编程语言排 ...
- C#学习笔记5
1.接口的显式实现:显式实现需要在实现接口的类型中,在实现接口的成员中添加接口名称的前缀.且没有必要添加public.virtual这些修饰符,因为显式实现只能通过接口调用,不能用实现类进行调用.为此 ...
- Java进程内缓存
今天和同事聊到了缓存,在Java中实现进程缓存.这里主要思想是,用一个map做缓存.缓存有个生存时间,过期就删除缓存.这里可以考虑两种删除策略,一种是起一个线程,定期删除过期的key.第二个是,剔除模 ...
- 关于controller和apicontroller的跨域实现过滤器的不同
1.controller的跨域访问 filter的实现请继承System.Web.Mvc.ActionFilterAttribute 2.apicontroller的跨域访问 filter的实现请继承 ...
- Canvas绘制图片模糊
canvas是html5的新标签,是个可以绘制图形的画布,画布的默认大小为300x150.在自定义绘制画布大小的时候有注意的问题,就是用样式来设置高度和宽度的时候 比如 <div style=& ...