【题目】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 异或的更多相关文章

  1. 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]; 首先说异或   ...

  2. Codeforces Round #539 (Div. 2) 异或 + dp

    https://codeforces.com/contest/1113/problem/C 题意 一个n个数字的数组a[],求有多少对l,r满足\(sum[l,mid]=sum[mid+1,r]\), ...

  3. Codeforces - 662A 思路巧妙的异或

    题意:给你\(n\)堆石子玩尼姆博弈,每堆石子可以是\(a_i\)也可以是\(b_i\),选择概率相等且每堆选择相互独立,求先手必胜(异或不为0)的概率 首先需要找出一种优雅的策略表示方法(利用异或的 ...

  4. Codeforces 1054D Changing Array 贪心+异或和

    题意 给一个长度为\(n\)的位数为\(k\)的整数数列\(a\),一次操作可将任意\(a_i\)取反,问经过任意次操作后最多有多少个区间异或和不为\(0\) 分析 求出前缀异或和,区间异或和为\(0 ...

  5. CodeForces.1174D.EhabandtheExpectedXORProblem(构造前缀异或和数组)

    题目链接 这道题比赛的时候没做出来,赛后补题的时候发现其实可以构造一个前缀异或和数组,然后根据初始化的第一个值进行填数,但是作为菜鸡的我虽然坚信自己的想法是正确的却想了很久也没有能够构造出来所谓的前缀 ...

  6. codeforces div2 603 D. Secret Passwords(并查集)

    题目链接:https://codeforces.com/contest/1263/problem/D 题意:有n个小写字符串代表n个密码,加入存在两个密码有共同的字母,那么说这两个密码可以认为是同一个 ...

  7. Codeforces 251D - Two Sets(异或方程组)

    题面传送门 题意: 你有一个可重集 \(S=\{a_1,a_2,\dots,a_n\}\),你要把它划分成两个可重集 \(S_1,S_2\) 使得 \(S\) 中每个元素都恰好属于 \(S_1\) 与 ...

  8. CodeForces 496B Secret Combination

    Secret Combination Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u ...

  9. 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 ...

随机推荐

  1. js实现随机的四则运算题目

    老师给出的题,写一个小程序,可以生成随机的四则运算题目给给小学生用.以前自己就写了一个四则运算的简单js小程序,是这样的: 事件 + - * / 这是个自己输入的算法,但要求是自动产生随机数.于是我用 ...

  2. 《Linux内核分析与实现》 第四周 读书笔记

    第五章 系统调用 20135307 张嘉琪 5.1 与内核通信 系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层主要作用有三个: 它为用户空间提供了一种硬件的抽象接口 系统调用保证了系统的稳 ...

  3. C语言版本:单链表的实现

    slist.h #ifndef __SLIST_H__ #define __SLIST_H__ #include<cstdio> #include<malloc.h> #inc ...

  4. 初学Hadoop之单机模式环境搭建

    本文仅作为学习笔记,供大家初学Hadoop时学习参考.初学Hadoop,欢迎有经验的朋友进行指导与交流! 1.安装CentOS7 准备 CentOS系统镜像CentOS-7.0-1406-x86_64 ...

  5. Docker(一)-Docker介绍

    什么就Docker? Docker是一个开源项目, 诞生于2013年初,最初是dotCloud公司内部的一个业余项目.它基于Google公司推出的Go语言实现.项目后来加入了Linux基金会,遵从了A ...

  6. Windows server 自带的 .net版本

    1. Win2012r2 所带的版本: 2. Win2016 所带的版本 4.6 Win2019 自带的 .net版本为: 4.7 4. 然后比较 Win2008r2sp1 使用的是 .net3.5 ...

  7. [转帖]Linux系统/dev/mapper目录浅谈

    Linux系统/dev/mapper目录浅谈   Linux系统的一般的文件系统名称类似于/dev/sda1或/dev/hda1,但是今天在进行系统维护的时候,利用df -h 命令敲出了/dev/ma ...

  8. asp、asp.net、.aspx、.ascx、.ashx的简单说明

    ASP是动态server页面(Active Server Page)的英文缩写.[1]是微软公司开发的取代CGI脚本程序的一种应用.它能够与数据库和其他程序进行交互,是一种简单.方便的编程工具.ASP ...

  9. [转帖] Oracle数据库 通过触发器 限制登录ip

    转帖 From https://yq.aliyun.com/ziliao/123360 create or replace trigger logon_ip_control after logon o ...

  10. [转帖] Windows 与linux的栈大小问题

    一般来说,我们所用的内存有栈和堆之分,其它的我们很少控制,栈的速度快,但是空间小.不灵活:而堆的空间几乎可以满足任何要求.灵活,但是相对的速度要慢了很多,并且在VC中堆是人为控制的,new了就要del ...