noi.ac309 Mas的童年
题面
题目描述
\(Mas\)完成了一天的工作,走在回家的路上,看着路边的景色,他想起来自己的童年。
许许多多的记忆交错,丝丝缕缕的牵扯着\(Mas\)。
在回忆的深处,\(Mas\)想起来了一个常常在幼儿园玩的游戏。
有\(n\)个小朋友一起排成一排,然后小朋友们会一起开始跳舞。
聪明的\(Mas\)发现,每个小朋友都有自己的高兴程度,对于第\(i\)个小朋友,他的高兴程度是\(ai\)。
当一排高兴程度分别为\(b_1,b_2,…,b_k\)的\(k\)个小朋友跳舞的时候,他们会产生\(b1 \otimes b2 \otimes ⋯\otimes bk\)的愉悦值。
但是\(Mas\)觉得不够尽兴,于是他决定让小朋友们从某个位置分开,让原本一排的队伍分成两排,从而使两排新队伍的愉悦值加起来最大,当然,是有可能不分成两排的。
具体的,对于一排kk个小朋友,他们的高兴程度分别是\(b_1,b_2,…,b_k\),\(Mas\)会找到位置\(i\in [0,k),使得(b1\otimes ⋯\otimes bi)+(bi+1\otimes ⋯\otimes bk)\)最大。
回想起这个游戏的\(Mas\)决定再来玩一下这个游戏,于是他想起来了某一天排成一排的\(n\)个小朋友的高兴程度\(a1,a2,…,an\)对于\(i=1..n\),\(Mas\)希望求出前\(i\)个小朋友排成的队伍中通过拆分成两个队伍能够得到的最大愉悦值的和是多少。
输入
第一行一个正整数\(n\)表示小朋友的数量。
第二行\(n\)个整数,表示\(a_{1..n}\)。
输出
一行\(n\)个整数表示答案。
思路
读完拉么长的题面。发现他其实就是对于每个位置要求这个东西
\]
其中\(S_i\)表示前\(i\)个元素的异或和。
然后根据\(a+b = a\otimes b + (a \& b) \times 2\)
这个证明的话很显然:因为异或相当于不进位的加法。用\(\&\)可以求出需要进位的位置。然后乘二在相加就可以啦。
这样我们就可以把要求的式子变成这个样子
\]
\]
因为\(S_i\)是确定的,只要让\(S_i \otimes S_j \& S_j\)最大就行了。
然后我们按位思考。对于二进制下的第\(k\)位。如果\(S_i\)的这一位为\(1\),那么不管\(S_j\)这一位是什么,肯定都无法将答案的这一位变成\(1\)。
所以我们就想要让\(S_i\)为\(0\)的那些位置尽可能变成\(1\)。
对于每个\(S_j\),我们将他和他的子集标记一下。然后贪心的从高位到低位将\(S_i\)为\(0\)的位置变为\(1\).
并且查看当前的答案是不是之前标记过。
具体看代码吧
代码
/*
* @Author: wxyww
* @Date: 2019-03-30 08:10:10
* @Last Modified time: 2019-03-31 08:31:43
*/
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
using namespace std;
typedef long long ll;
const int N = 2000000 + 100;
ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') {
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int s[N];
bool vis[N];
void ins(int x) {
if(vis[x]) return;
vis[x] = true;
for(int i = 0;i <= 20;++i) {
if((x >> i) & 1) ins(x - (1 << i));
}
}
int solve(int x) {
int ret = 0;
int k = x ^ ((1 << 21) - 1);
for(int i = 20;i >= 0;--i)
if(((k >> i) & 1) && vis[(ret + (1 << i))])
ret += (1 << i);
return ret;
}
int main() {
int n = read();
for(int i = 1;i <= n;++i) s[i] = s[i - 1] ^ read();
vis[0] = true;
for(int i = 1;i <= n;++i) {
printf("%d ",solve(s[i]) * 2 + s[i]);
ins(s[i]);
}
return 0;
}
noi.ac309 Mas的童年的更多相关文章
- 【noi.ac】#309. Mas的童年
#309. Mas的童年 链接 分析: 求$max \{sj + (s_i \oplus s_j)\}$ 因为$a + b = a \oplus b + (a \& b) \times 2$ ...
- noi.ac#309 Mas的童年(子集乱搞)
题意 题目链接 Sol 记\(s_i\)表示前\(i\)个数的前缀异或和,我们每次相当于要找一个\(j\)满足\(0 < j < i\)且\((s_i \oplus s_j) + s_j\ ...
- Noi.ac #309. Mas的童年(贪心)
/* 用所谓的加法拆分操作得到 x + y = (x ^ y) + 2 * (x & y) 那么我们这两段异或相当于前缀和 + 2 * 分段使左右两块&最大 记当前前缀异或和为S, 那 ...
- [NOI.AC省选模拟赛3.30] Mas的童年 [二进制乱搞]
题面 传送门 思路 这题其实蛮好想的......就是我考试的时候zz了,一直没有想到标记过的可以不再标记,总复杂度是$O(n)$ 首先我们求个前缀和,那么$ans_i=max(pre[j]+pre[i ...
- # NOI.AC省选赛 第五场T1 子集,与&最大值
NOI.AC省选赛 第五场T1 A. Mas的童年 题目链接 http://noi.ac/problem/309 思路 0x00 \(n^2\)的暴力挺简单的. ans=max(ans,xor[j-1 ...
- NOI2019 SX 模拟赛 no.5
Mas 的童年 题目描述:不知道传送门有没有用? 反正就是对于每个前缀序列求一个断点,使得断点左右两个区间的 分别的异或和 的和最大 分析 jzoj 原题? 但是我 TM 代码没存账号也过期了啊! 然 ...
- NOI2019省选模拟赛 第五场
爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...
- 从一道NOI练习题说递推和递归
一.递推: 所谓递推,简单理解就是推导数列的通项公式.先举一个简单的例子(另一个NOI练习题,但不是这次要解的问题): 楼梯有n(100 > n > 0)阶台阶,上楼时可以一步上1阶,也可 ...
- NOI 动态规划题集
noi 1996 登山 noi 8780 拦截导弹 noi 4977 怪盗基德的滑翔翼 noi 6045 开餐馆 noi 2718 移动路线 noi 2728 摘花生 noi 2985 数字组合 no ...
随机推荐
- IntelliJ IDEA下的使用git
1.git简介 git是目前流行的分布式版本管理系统.它拥有两套版本库,本地库和远程库,在不进行合并和删除之类的操作时这两套版本库互不影响.也因此其近乎所有的操作都是本地执行,所以在断网的情况下任然可 ...
- int 与 Integer 的区别
int和Integer的区别 Integer是int的包装类,int则是java的一种基本数据类型 Integer变量必须实例化后才能使用,而int变量不需要 Integer实际是对象的引用,当new ...
- nodejs异步转同步
项目在微信环境开发,需要获取access_token进行授权登录和获取用户信息. 特意把这块功能拿出来封装一个自定义module module.exports = new Wechat(con.app ...
- PM过程能力成熟度4级
话说3级的PM已经非常厉害了,但仍然处于定性阶段.如何才能不动声色的跟BOSS过招?PM 4级就是让数字变成你的嘴巴,开启项目管理的量化大门.因此,4级PM的工作重心(详见上一篇文章中的表格),也会逐 ...
- 好代码是管出来的——C#的代码规范
代码是软件开发过程的产物,代码的作用是通过编译器编译后运行,达到预期的效果(功能.稳定性.安全性等等),而另外一个重要作用是给人阅读.对于机器来说只要代码正确就能够正确的运行程序,但是人不同,如果代码 ...
- name 'reload' is not defined解决方法
今天在学习scrapy的时候,在网上找了一段代码,运行出了一点问题. 命令行报错: name 'reload' is not defined 原因是,python版本的问题 原代码如下: import ...
- Parameter 'ids' not found. Available parameters are [array]
传的参数是一个数组, Long[] ids 后台错误写法 <delete id="deleteById"> delete from table where id in ...
- Java基础系列--06_抽象类与接口概述
抽象类 (1)如果多个类中存在相同的方法声明,而方法体不一样,我们就可以只提取方法声明. 如果一个方法只有方法声明,没有方法体,那么这个方法必须用抽象修饰. 而一个类中如果有抽象方法,这个类必须定义为 ...
- 在Winform开发框架中对附件文件进行集中归档处理
在我们Winform开发中,往往需要涉及到附件的统一管理,因此我倾向于把它们独立出来作为一个附件管理模块,这样各个模块都可以使用这个附件管理模块,更好的实现模块重用的目的.在涉及附件管理的场景中,一个 ...
- Python学习案例之Web版语音合成播报
前言 语音合成技术能将用户输入的文字,转换成流畅自然的语音输出,并且可以支持语速.音调.音量设置,打破传统文字式人机交互的方式,让人机沟通更自然. 应用场景 将游戏场景中的公告.任务或派单信息通过语音 ...