@topcoder - SRM577D1L3@ XorAndSum
@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的更多相关文章
- TopCoder kawigiEdit插件配置
kawigiEdit插件可以提高 TopCoder编译,提交效率,可以管理保存每次SRM的代码. kawigiEdit下载地址:http://code.google.com/p/kawigiedit/ ...
- 记第一次TopCoder, 练习SRM 583 div2 250
今天第一次做topcoder,没有比赛,所以找的最新一期的SRM练习,做了第一道题. 题目大意是说 给一个数字字符串,任意交换两位,使数字变为最小,不能有前导0. 看到题目以后,先想到的找规律,发现要 ...
- TopCoder比赛总结表
TopCoder 250 500 ...
- Topcoder几例C++字符串应用
本文写于9月初,是利用Topcoder准备应聘时的机试环节临时补习的C++的一部分内容.签约之后,没有再进行练习,此文暂告一段落. 换句话说,就是本文太监了,一直做草稿看着别扭,删掉又觉得可惜,索性发 ...
- TopCoder
在TopCoder下载好luncher,网址:https://www.topcoder.com/community/competitive%20programming/ 选择launch web ar ...
- TopCoder SRM 596 DIV 1 250
body { font-family: Monospaced; font-size: 12pt } pre { font-family: Monospaced; font-size: 12pt } P ...
- 求拓扑排序的数量,例题 topcoder srm 654 div2 500
周赛时遇到的一道比较有意思的题目: Problem Statement There are N rooms in Maki's new house. The rooms are number ...
- TopCoder SRM 590
第一次做TC,不太习惯,各种调试,只做了一题...... Problem Statement Fox Ciel is going to play Gomoku with her friend ...
- Topcoder Arena插件配置和训练指南
一. Arena插件配置 1. 下载Arena 指针:http://community.topcoder.com/tc?module=MyHome 左边Competitions->Algorit ...
随机推荐
- random模块&hashlib模块
random模块1.random.randrange(1, 10):返回1-10之间的一个随机数,不包括102.random.randint(1,10):返回1-10之间的一个随机数,包括103.ra ...
- session失效刷新后登录页面嵌入在iframe中的解决办法
在login页面中添加以下一段代码: var _topWin = window; while (_topWin != _topWin.parent.window) { _topWin ...
- Python实例 类和继承
class Base: def __init__(self): self.data = [] def add(self, x): self.data.a ...
- 洛谷P1757 通天之分组背包 [2017年4月计划 动态规划06]
P1757 通天之分组背包 题目背景 直达通天路·小A历险记第二篇 题目描述 自01背包问世之后,小A对此深感兴趣.一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品 ...
- Codeforces 113B
题目链接 B. Petr# time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...
- LintCode 合并二维数组
合并两个排序的整数数组A和B变成一个新的数组. 样例 给出A=[1,2,3,4],B=[2,4,5,6],返回 [1,2,2,3,4,4,5,6] 之前想的是用剑指offer里替换空格那种方法 但是把 ...
- R语言基础画图/绘图/作图
R语言基础画图/绘图/作图 R语言基础画图 R语言免费且开源,其强大和自由的画图功能,深受广大学生和可视化工作人员喜爱,这篇文章对如何使用R语言作基本的图形,如直方图,点图,饼状图以及箱线图进行简单介 ...
- ubuntn 18 开起ssh 并用root远程登陆
原文:ubuntn 18 开起ssh 并用root远程登陆 版权声明:本文为博主原创文章,随意转载. https://blog.csdn.net/Michel4Liu/article/details/ ...
- php去除文件bom头
有时候在ajax返回的json数据前多出一些不明的字符,就是所谓的bom头,导致javascript解析json格式失败,下面贴出一段PHP代码实现检测和去除bom头. <?php header ...
- 移动端适配之二:visual viewport、layout viewport和ideal viewport介绍
上一篇博文,可算把像素这个东西讲清楚了.在这篇博文里面,将继续介绍viewport相关的内容. 很多博客都会提到PPK所讲的三个viewport,有的讲的比较复杂,看的云里雾里,我这里也大概介绍一下, ...