【CodeForces】925 C.Big Secret 异或
【题目】C.Big Secret
【题意】给定数组b,求重排列b数组使其前缀异或和数组a单调递增。\(n \leq 10^5,1 \leq b_i \leq 2^{60}\)。
【算法】异或
为了拆位分析,先考虑一个简单的问题:已知一个合法b数组和一个数字"1",求数字”1“是否能插入?
容易发现,”1“插入的位置必须满足前面的数字中有偶数个奇数(可以是0个),因为这样前缀和才能比上一位多1,满足要求。
进一步的,已知一个有y个奇数的合法b数组和x个数字”1“,求数字”1“能否全部插入?
利用上面的结论,容易发现当x<=y+1时,只需要在最前面放一个”1“,然后每隔一个奇数放一个”1“就能满足要求(”1“本身也是奇数)。
而当x>y+1时,无解。
上面这个结论可以扩展,对于第k位,已知有y个第k位为0的数字的合法b数组,和x个第k位为1的在\([1,2^{k+1}-1]\)范围内的数字,求数字能否全部插入?
为什么这样扩展是正确的?一个数字能否插入其实只取决于它的最高的1。因为如果最高位异或变成0,无论低位如何都不合法。如果最高为异或变成1,无论低位如何都合法。
现在考虑做法,如何在插入时保证不跳过每次前缀和为偶数的情况?预处理v[i]表示最高的”1“在第i位的数字列表,从前往后依次确定答案,从低位到高位枚举合法的位数并且数字列表不空就插入,累加前缀和。从低到高枚举就能保证插入的数字的低位一定都是不能插入的,免得低位的”1“使得跳过了前缀和为偶数的情况。
复杂度\(O(60*n)\)。
本题的关键在于从将数字插入已有的合法数列的角度考虑。
#include<cstdio>
#include<vector>
#define ll long long
using namespace std;
vector<ll>v[70];
int n;ll ans[100010],cur=0;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
ll u;scanf("%lld",&u);
for(int j=60;j>=0;j--)if((u>>j)&1){v[j].push_back(u);break;}
}
for(int i=1;i<=n;i++){
bool ok=0;
for(int j=0;j<=60;j++)if(!(cur&(1ll<<j))&&!v[j].empty()){
cur^=(ans[i]=v[j].back());v[j].pop_back();ok=1;break;
}
if(!ok){puts("No");return 0;}
}
for(int i=1;i<=n;i++)printf("%lld ",ans[i]);
return 0;
}
【CodeForces】925 C.Big Secret 异或的更多相关文章
- codeforces 925 c big secret
题意: 给你n个数,b[1],b[2],b[3].......,让你重新排列,使a[i]的值递增 a[i]和b的关系: a[i] = b[1]^b[2]^b[3]^....^b[i]; 首先说异或 ...
- Codeforces Round #539 (Div. 2) 异或 + dp
https://codeforces.com/contest/1113/problem/C 题意 一个n个数字的数组a[],求有多少对l,r满足\(sum[l,mid]=sum[mid+1,r]\), ...
- Codeforces - 662A 思路巧妙的异或
题意:给你\(n\)堆石子玩尼姆博弈,每堆石子可以是\(a_i\)也可以是\(b_i\),选择概率相等且每堆选择相互独立,求先手必胜(异或不为0)的概率 首先需要找出一种优雅的策略表示方法(利用异或的 ...
- Codeforces 1054D Changing Array 贪心+异或和
题意 给一个长度为\(n\)的位数为\(k\)的整数数列\(a\),一次操作可将任意\(a_i\)取反,问经过任意次操作后最多有多少个区间异或和不为\(0\) 分析 求出前缀异或和,区间异或和为\(0 ...
- CodeForces.1174D.EhabandtheExpectedXORProblem(构造前缀异或和数组)
题目链接 这道题比赛的时候没做出来,赛后补题的时候发现其实可以构造一个前缀异或和数组,然后根据初始化的第一个值进行填数,但是作为菜鸡的我虽然坚信自己的想法是正确的却想了很久也没有能够构造出来所谓的前缀 ...
- codeforces div2 603 D. Secret Passwords(并查集)
题目链接:https://codeforces.com/contest/1263/problem/D 题意:有n个小写字符串代表n个密码,加入存在两个密码有共同的字母,那么说这两个密码可以认为是同一个 ...
- Codeforces 251D - Two Sets(异或方程组)
题面传送门 题意: 你有一个可重集 \(S=\{a_1,a_2,\dots,a_n\}\),你要把它划分成两个可重集 \(S_1,S_2\) 使得 \(S\) 中每个元素都恰好属于 \(S_1\) 与 ...
- CodeForces 496B Secret Combination
Secret Combination Time Limit:2000MS Memory Limit:262144KB 64bit IO Format:%I64d & %I64u ...
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined)D. Felicity's Big Secret Revealed
题目连接:http://codeforces.com/contest/757/problem/D D. Felicity's Big Secret Revealed time limit per te ...
随机推荐
- muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制
目录 muduo网络库学习笔记(四) 通过eventfd实现的事件通知机制 eventfd的使用 eventfd系统函数 使用示例 EventLoop对eventfd的封装 工作时序 runInLoo ...
- openstack 主机无法ping通instance,无法ssh到instance
https://docs.openstack.org/zh_CN/user-guide/cli-nova-configure-access-security-for-instances.html 好不 ...
- [文章存档]Azure上部署的java app在向第三方服务传送中文时出现乱码
https://docs.azure.cn/zh-cn/articles/azure-operations-guide/app-service-web/aog-app-service-web-java ...
- group by 和count的联合使用问题 [转]
group by 和count的联合使用问题 今天写查询语句遇到一个问题,就是用group by进行分组以后,用count统计分组以后的个数, 开始写的语句大体是: select count(m.fb ...
- LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下)
LINUX内核分析第五周学习总结——扒开应用系统的三层皮(下) 张忻(原创作品转载请注明出处) <Linux内核分析>MOOC课程http://mooc.study.163.com/cou ...
- 基于Struts2+Hibernate的朋友圈留言网站开发的质量属性
在课堂上我们了解了质量高于功能,质量属性是指影响质量的相关因素,是对质量的描述.现在我们对基于SSH的交友网站开发的质量属性可以从以下几个方向进行分析: (1)可用性: 当错误发生时,使用可用性战术进 ...
- “数学口袋精灵”第二个Sprint计划---第一天
“数学口袋精灵”第二个Sprint计划----第一天进度 任务分配: 冯美欣:欢迎界面的音效 吴舒婷:游戏界面的动作条,选择答案后的音效 林欢雯:完善算法代码的设计 进度: 冯美欣:上网百度音乐资 ...
- Alpha版本事后诸葛亮
目录 设想和目标 计划 资源 变更管理 设计/实现 测试/发布 团队的角色,管理,合作 总结: 本小组和其他组的评分 分工和贡献分 全组讨论的照片 问题 第一组提问回答:爸爸饿了队 第二组提问回答:拖 ...
- 单片机pc指针
单片机的PC是指程序计数器(Program Counter).程序计数器PC用于存放下一条将要执行的指令地址,是一个16位专用寄存器,不能通过MOV指令来操作,对用户来说是不可见的.当执行一条指令时, ...
- 【Leetcode】535. Encode and Decode TinyURL
Question: TinyURL is a URL shortening service where you enter a URL such as https://leetcode.com/pro ...