@description@

给出 N 个数,每次操作可以任意选择两个数,将其中一个替换为两个数的异或。

求任意次操作后,最终所有数的和的最大值。

Class:

XorAndSum

Method:

maxSum

Parameters:

long[]

Returns:

long

sample:

{1,2,3}

Returns: 8

constraints

数的数量 N <= 50,保证所有数的权值 <= 10^15。

@solution@

最大、异或这些关键字,不难想到线性基。

同时可以发现,题目中给出的操作颇有些像高斯消元中,将一个方程异或到另一个方程的操作。

这更坚定了我们写线性基的决心。

我们可以类比高斯消元的做法,将线性基外的数全部消成 0,然后再通过线性基异或成可以异或得到的最大值。

考虑线性基中的数怎么才能取到最大值。

我们将线性基继续类比高斯消元进行简化,将每一行的主元(如果有)所在列全部异或成 0。

然后?可以发现一个大小为 k 的线性基可以异或出 2^k 种数,而我们一共有 k 个主元,决定每一个主元是选还不是选的方案数也是 2^k。进而两者是一一对应的。

我们希望最终线性基中的每一个数都是最大值:即选择所有的主元的那种方案。但是我们可以发现,根据线性基的定义可以简单反证假如有两个以上的主元在自己所在列的每一行中都为 1,会导致矛盾。

这意味着对于主元所在的列,必然存在一个 0,只有一列会例外。显然我们将这个例外放在最大的主元是最优的。

于是线性基中最大和就可以构造出来了:有一个数是选择所有主元(即能异或出的最大值),其他数总是缺一个主元。

我也不知道我上面写了啥。大家也可以看看yhn学长的博客

@accepted code@

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef long long ll;
class XorAndSum{
public:
ll b[60 + 5];
void insert(ll x) {
for(int i=60;i>=0;i--)
if( x & (1LL<<i) ) {
if( b[i] == 0 )
b[i] = x;
x ^= b[i];
}
}
ll get_max() {
for(int i=60;i>=0;i--)
for(int j=i-1;j>=0;j--)
if( b[i] & (1LL<<j) )
b[i] ^= b[j];
ll ret = 0;
for(int i=60;i>=0;i--)
ret ^= b[i];
return ret;
}
ll maxSum(vector<ll>v) {
for(int i=0;i<v.size();i++)
insert(v[i]);
ll x = get_max(), ans = v.size()*x;
bool fir = true;
for(int i=60;i>=0;i--)
if( b[i] ) {
if( fir )
fir = false;
else
ans = ans - x + (x^b[i]);
}
return ans;
}
};

@details@

老师:这个不是线性基的入门题?你考试的时候连这个都写不起?

我:……

怎么办整个世界都在嘲讽我。。。

@topcoder - SRM577D1L3@ XorAndSum的更多相关文章

  1. TopCoder kawigiEdit插件配置

    kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...

  2. 记第一次TopCoder, 练习SRM 583 div2 250

    今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...

  3. TopCoder比赛总结表

    TopCoder                        250                              500                                 ...

  4. Topcoder几例C++字符串应用

    本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...

  5. TopCoder

    在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...

  6. TopCoder SRM 596 DIV 1 250

    body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...

  7. 求拓扑排序的数量,例题 topcoder srm 654 div2 500

    周赛时遇到的一道比较有意思的题目: Problem Statement      There are N rooms in Maki's new house. The rooms are number ...

  8. TopCoder SRM 590

     第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement     Fox Ciel is going to play Gomoku with her friend ...

  9. Topcoder Arena插件配置和训练指南

    一. Arena插件配置 1. 下载Arena 指针:http://community.topcoder.com/tc?module=MyHome 左边Competitions->Algorit ...

随机推荐

  1. const属性与容器元素排序

    给容器里元素排序时,会破坏容器的const的属性:因此当你在一个函数传参的时候如果使用的是const T&:那么你在调用qt的qsort给容器排序的时候可能会遭遇一些看不懂的BUG提示 类似: ...

  2. ES6中async和await说明和用法

    昨天看了一篇vue的教程,作者用async/ await来发送异步请求,从服务端获取数据,代码很简洁,同时async/await 已经被标准化,是时候学习一下了. 先说一下async的用法,它作为一个 ...

  3. TP3.2.x判断手机端访问并设置默认访问模块的方法 - ThinkPHP框架

    手机端访问时调用Wap手机模块,实现在手机端访问时展示出手机网站,无需跳转域名首先我们在./Application/Common/Conf/ 目录下建立两个公共配置文件:config.php 和con ...

  4. python之pip

    sudo vim /usr/bin/lsb_release 确保第一行是python2.7,不然无法使用pip安装第三方依赖

  5. C++ 实现十大排序算法

    教你手撕排序,这里有一个概念就是稳定排序.假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前, ...

  6. C# System.Timers.Timer中的坑,程序异常退出后timer依然运行问题

    问题背景 C#小白,由于本公司IM系统服务端(java)是本人独立开发的,加上现在所在项目需要对接IM系统,于是IM的客户端(C#实现)对接工作就交给我了.于是C#小白的我天真的以为只要调用C#端的S ...

  7. 详细介绍Java中的堆、栈和常量池

    下面主要介绍JAVA中的堆.栈和常量池: 1.寄存器 最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制. 2. 栈 存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在 ...

  8. NOIP模拟 17.8.15

    NOIP模拟17.8.15 A 债务文件名 输入文件 输出文件 时间限制 空间限制debt.pas/c/cpp debt.in debt.out 1s 128MB[题目描述]小 G 有一群好朋友,他们 ...

  9. node.js对象数据类型

    在这里复习下前端JS的数据类型:前端JS中的数据类型: 1.基本/原生/值类型 string.number.boolean.null.undefined 2.引用/对象类型    ES对象类型:Str ...

  10. HZOI20190714 T3建造游乐场

    先放作者的正解: 先说g吧,有i个点的话,在其中i-1个点中有$C_{i-1}^{2}$种边,每个边有选和不选两种情况.如果度不是偶数呢?用剩下那个点给他连上呗.如果剩下那个点度数不是偶数呢?这是不可 ...