传送门

题意:

给出\(n\)个数\(a_i\),现在要将其分为两堆,使得这两堆数的异或和相加最大。

思路:

  • 考虑线性基贪心求解。
  • 但直接上线性基求出一组的答案是行不通的,原因之后会说。
  • 注意到如果二进制中某一位\(1\)的个数出现了奇数次,那么无论怎么分,都会有一组中这位为\(1\);对于出现偶数次的位,两组中该位都可以有\(1\),或者都没有\(1\)。
  • 那么我们只需要贪心地插入二进制\(1\)的个数为偶数的那些位就行了,显然这样能使得最终答案最大。

下面口胡一下为什么不能直接用线性基来搞:

如果贪心地利用线性基直接求出一组答案,假设第\(i\)位二进制出现次数为奇数,那么我们可能就以\(i\)为基底,那么其余偶数位作为基底的"可能性"就降低了,所以我们在插入线性基的时候要避免奇数个数的位,这样能使答案最大。

#include <bits/stdc++.h>
#define fi first
#define se second
#define MP make_pair
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5; int n;
ll a[N], p[62];
bool chk[62]; void insert(ll x) {
for(int i = 60; i >= 0; i--) {
if(chk[i]) continue;
if(x >> i & 1) {
if(!p[i]) {
p[i] = x;
break;
}
x ^= p[i];
}
}
} int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
ll all = 0;
for(int i = 1; i <= n; i++) cin >> a[i], all ^= a[i];
for(int i = 0; i <= 60; i++) {
if(all >> i & 1) chk[i] = 1;
}
for(int i = 1; i <= n; i++) insert(a[i]);
ll ans = 0;
for(int i = 0; i <= 60; i++) {
if(chk[i])
for(int j = 0; j <= 60; j++) {
if(p[j] >> i & 1) {
p[j] ^= (1ll << i);
}
}
}
for(int i = 60; i >= 0; i--) {
if((p[i] ^ ans) > ans) ans = p[i] ^ ans;
}
cout << ans + (ans ^ all);
return 0;
}

P.S:实现的话可以一开始就将\(a\)数组\(chk\)了的位的值减去,就让这些位不参与运算,写起来能更加简洁。

如下:

Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define MP make_pair
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int N = 1e5 + 5; int n;
ll a[N], p[62]; void insert(ll x) {
for(int i = 60; i >= 0; i--) {
if(x >> i & 1) {
if(!p[i]) {
p[i] = x;
break;
}
x ^= p[i];
}
}
} int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n;
ll all = 0;
for(int i = 1; i <= n; i++) cin >> a[i], all ^= a[i];
for(int i = 0; i <= 60; i++) {
if(all >> i & 1) {
for(int j = 1; j <= n; j++) {
if(a[j] >> i & 1) a[j] -= (1ll << i);
}
}
}
for(int i = 1; i <= n; i++) insert(a[i]);
ll ans = 0;
for(int i = 60; i >= 0; i--) {
if((p[i] ^ ans) > ans) ans = p[i] ^ ans;
}
cout << ans + (ans ^ all);
return 0;
}

AtCoder abc 141 F - Xor Sum 3(线性基)的更多相关文章

  1. Atcoder ABC 141

    Atcoder ABC 141 A - Weather Prediction SB题啊,不讲. #include<iostream> #include<cstdio> #inc ...

  2. CodeForces - 1101G :(Zero XOR Subset)-less(线性基)

    You are given an array a1,a2,…,an of integer numbers. Your task is to divide the array into the maxi ...

  3. [WC2011]最大XOR和路径 线性基

    [WC2011]最大XOR和路径 LG传送门 需要充分发掘经过路径的性质:首先注意不一定是简单路径,但由于统计的是异或值,重复走是不会被统计到的,考虑对于任意一条从\(1\)到\(n\)的路径的有效部 ...

  4. CF1101G (Zero XOR Subset)-less 线性基

    传送门 既然每一次选择出来的都是一个子段,不难想到前缀和计算(然而我没有想到--) 设异或前缀和为\(x_i\),假设我们选出来的子段为\([1,i_1],(i_1,i_2],...,(i_{k-1} ...

  5. 洛谷P4151 [WC2011] 最大XOR和路径 [线性基,DFS]

    题目传送门 最大XOR和路径 格式难调,题面就不放了. 分析: 一道需要深刻理解线性基的题目. 好久没打过线性基的题了,一开始看到这题还是有点蒙逼的,想了几种方法全被否定了.还是看了大佬的题解才会做的 ...

  6. [luogu4151 WC2011] 最大XOR和路径 (线性基)

    传送门 输入输出样例 输入样例#1: 5 7 1 2 2 1 3 2 2 4 1 2 5 1 4 5 3 5 3 4 4 3 2 输出样例#1: 6 说明 [样例说明] 根据异或的性质,将一个数异或两 ...

  7. 2019年牛客多校第四场 B题xor(线段树+线性基交)

    题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...

  8. 牛客练习赛26 D xor序列 (线性基)

    链接:https://ac.nowcoder.com/acm/contest/180/D 来源:牛客网 xor序列 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他 ...

  9. Wannafly Winter Camp 2020 Day 5J Xor on Figures - 线性基,bitset

    有一个\(2^k\cdot 2^k\) 的全零矩阵 \(M\),给出 \(2^k\cdot 2^k\) 的 \(01\) 矩阵 \(F\),现在可以将 \(F\) 的左上角置于 \(M\) 的任一位置 ...

随机推荐

  1. [C1W4] Neural Networks and Deep Learning - Deep Neural Networks

    第四周:深层神经网络(Deep Neural Networks) 深层神经网络(Deep L-layer neural network) 目前为止我们学习了只有一个单独隐藏层的神经网络的正向传播和反向 ...

  2. 剑指Offer-22.从上往下打印二叉树(C++/Java)

    题目: 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 分析: 按层次打印二叉树的节点,重点就是我们在打印一层节点的时候,同时按顺序保存好当前节点的下一层节点,也就是左节点和右节点,当此层节点 ...

  3. Note | 期刊答复(response)

    第一次TPAMI回复整理的经验. 190926:TPAMI中了,特回来补充. 简洁 尤其对于问答型问题,一定要在前三句话就回答审稿人的问题:yes or no. 不要绕弯子,专注于审稿人问题,解决就行 ...

  4. java4wifidog_server_README

    项目地址:https://github.com/C-hill/java4wifidog_server 开发环境:Windows  JDK7  Tomcat6  Myeclipse8.5  MySQL5 ...

  5. MMM的又一周计划[2019 7.1→2019.7.7]

    发现今天是7.1然后又是星期一 来一发吧 本周目标: 1.二分图最佳匹配 2.网络流 3.HH的项链 4.洛谷rk前1000(目前1.1k) (upd:469) 5.AC260(35题,上周A了34, ...

  6. LeetCode 2:两数相加 Add Two Numbers

    ​给出两个 非空 的链表用来表示两个非负的整数.其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字.如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和 ...

  7. 生成 RSA 公钥和私钥的方法

    在使用 RSA 加密算法时,需要使用到一对 公钥 和 私钥,生成 公钥 和 私钥 需要借助 openssl 这款工具,下载这款工具的地址如下: http://slproweb.com/products ...

  8. iframe嵌套页面中的跳转

    简单说一下场景. 假设有A.B.C和D四个JSP页面,D通过iframe嵌套在C中,C通过iframe嵌套在B中,B通过iframe嵌套在A中. 然后现在在D中编写JavaScript代码跳转页面. ...

  9. 【译】.NET Core 是 .NET 的未来

    为什么要翻译咧,.NET 5 都宣布在 .NET Core 之后发布咯,何不再给 .NET Core 打打鸡血,我这个 .NET Core 的死忠粉. 原文:<.NET Core is the ...

  10. Chrome教程之使用Chrome DevTools命令菜单运行命令

    1.模拟移动设备 点击 Toggle Device Toolbar 2.限制网络流量和 CPU 占用率 要限制网络流量和 CPU 占用率,请从 Throttle 列表中选择 Mid-tier mobi ...