「题解」agc031_c Differ by 1 Bit
本文将同步发布于:
题目
题目链接:洛谷 AT4693、AtCoder agc031_c。
题意概述
给定三个数 \(n,a,b\),求一个 \(0\sim 2^n-1\) 的排列满足下列三个条件:
- \(p_1=a\);
- \(p_{2^n}=b\);
- \(\operatorname{popcount}(p_i\oplus p_{i+1})=1\),其中 \(\oplus\) 表示按位异或。
请你判定是否可以构造并输出方案(若可以)。
题解
启发式的画图
直接考虑这个问题,似乎有些困难?
我们先用简单的语言,将它转化为一个图论问题。
图论转化
如果两个整数 \(a,b\in[0,2^n)\),满足 \(\operatorname{popcount}(a\oplus b)=1\),那么我们就在 \(a,b\) 之间连一条边。
那么问题转化为了给定起点与终点,求一条长度为 \(2^n\) 的简单路径。
转化成了图论问题,我们肯定要用几何直观来看看这个图到底是什么样子,采用画图工具 Graph Editor,取 \(n=2,3\) 时:
图片 \(n=2\):
图片 \(n=3\):
这提醒我们,整个图将会形成一个 \(n\) 维立方体。
具体地,我们考虑证明这件事,非常简单,换个角度即可。我们将一个二进制数各位上的数分开,看作各个维度的坐标值,例如 \(0=(00)_2\to (0,0),2=(10)_2\to (1,0)\)。那么我们不难得到此结论。
熟练解决图论问题
我们不难发现,这个图是一个二分图,其中左部点编号对应的二进制数中 \(1\) 的个数为偶数,右部点编号对应的二进制数中 \(1\) 的个数为奇数。
我们由此得到结论,如果存在答案,那么 \(\operatorname{popcount}(a\oplus b)\equiv 1\pmod 2\)。
这个条件对解的必要性已经得到证明,下面我们通过构造来证明其充分性。
构造与递推
首先为了化简问题,我们不难发现从 \(a\) 走到 \(b\) 等价于从 \(0\) 走到 \(a\oplus b\),这是因为异或的自反律与交换律,即 \(p_i\oplus x\oplus p_{i+1}\oplus x=p_i\oplus p_{i+1}\)。
对于 \(n\) 维立方体,它一定是由两个 \(n-1\) 维立方体上下拼接而成。
因此,我们考虑用类似数学归纳法的方式进行构造。
我们具有归纳基础,因为显然我们会 \(n=1\) 时的情况(一条线段从 \(0\) 走到 \(1\));
我们考虑如何通过 \(n-1\) 维的方案构造 \(n\) 维的方案,我们决定分类讨论:
- 根据上面的理论,我们分类讨论终点的位置(起点为 \(0\));
- 终点 \(t\) 与起点在不同的层:我们找到一条合法的从起点走 \(n-1\) 维空间到达 \(x\) 的方案,然后 \(x\) 走到另一层对应的点 \(x'\),再在 \(n-1\) 维空间中从 \(0\) 走到 \(t\oplus x'\) 的方案,\(x\) 可任取;
- 终点 \(t\) 与起点在同一层:我们直接从 \(0\) 走到 \(t\),然后把路径从路径中任意两个相邻点之间直接分割开来,在中间插入一个下层的 \(n-1\) 维的路径。
上面的文字叙述可能有点难懂,我们画个三维空间的图:
第一种情况:
第二种情况:
至此,我们用构造的方法证明了条件的充分性,可解决本题。
时间复杂度为 \(T(n)=2T(n-1)+\Theta(2^n)\),分析可知为 \(\Theta(2^nn)\)。
参考程序
参考程序中情况一选取 \(x=1\),情况二选取起点和路径的第二个点。
__builtin_parity(x)
表示求 \(x\) 的二进制表示中 \(1\) 的个数的奇偶性,奇数为 \(1\),偶数为 \(0\)。
#include<bits/stdc++.h>
using namespace std;
#define reg register
typedef long long ll;
#define flush() (fwrite(wbuf,1,wp1,stdout),wp1=0)
#define putchar(c) (wp1==wp2&&(flush(),0),wbuf[wp1++]=c)
static char wbuf[1<<21];int wp1;const int wp2=1<<21;
inline void write(reg int x){
static char buf[32];
reg int p=-1;
if(!x) putchar('0');
else while(x) buf[++p]=(x%10)^'0',x/=10;
while(~p) putchar(buf[p--]);
return;
}
inline void writeln(const char *s){
while(*s) putchar(*(s++));
putchar('\n');
return;
}
const int MAXN=17;
inline void solve(reg int x,reg int a,reg int ans[]){
if(!x)
ans[0]=0;
else if(x==1)
ans[0]=0,ans[1]=1;
else{
reg int val=1<<(x-1);
if(a&val){
solve(x-1,1,ans),solve(x-1,a^(val+1),ans+val);
for(reg int i=val;i<(1<<x);++i)
ans[i]=ans[i]^(val+1);
}
else{
solve(x-1,a,ans),solve(x-1,ans[1],ans+val);
for(reg int i=val;i<(1<<x);++i)
ans[i]=ans[i]^val;
static int tmp[1<<MAXN];
tmp[0]=ans[0];
for(reg int i=0;i<val;++i)
tmp[i+1]=ans[i+val];
for(reg int i=val+1;i<(1<<x);++i)
tmp[i]=ans[i-val];
for(reg int i=0;i<(1<<x);++i)
ans[i]=tmp[i];
}
}
return;
}
int n,A,B;
int ans[1<<MAXN];
int main(void){
scanf("%d%d%d",&n,&A,&B);
B^=A;
if(__builtin_parity(B)){
writeln("YES");
solve(n,B,ans);
reg int U=(1<<n)-1;
for(reg int i=0;i<=U;++i)
write(ans[i]^A),putchar(i==U?'\n':' ');
}
else
writeln("NO");
flush();
return 0;
}
「题解」agc031_c Differ by 1 Bit的更多相关文章
- 「题解」「美团 CodeM 资格赛」跳格子
目录 「题解」「美团 CodeM 资格赛」跳格子 题目描述 考场思路 思路分析及正解代码 「题解」「美团 CodeM 资格赛」跳格子 今天真的考自闭了... \(T1\) 花了 \(2h\) 都没有搞 ...
- 「题解」「HNOI2013」切糕
文章目录 「题解」「HNOI2013」切糕 题目描述 思路分析及代码 题目分析 题解及代码 「题解」「HNOI2013」切糕 题目描述 点这里 思路分析及代码 题目分析 这道题的题目可以说得上是史上最 ...
- 「题解」JOIOI 王国
「题解」JOIOI 王国 题目描述 考场思考 正解 题目描述 点这里 考场思考 因为时间不太够了,直接一上来就着手暴力.但是本人太菜,居然暴力爆 000 ,然后当场自闭- 一气之下,发现对 60pts ...
- 「题解」:[loj2763][JOI2013]现代豪宅
问题 A: 现代豪宅 时间限制: 1 Sec 内存限制: 256 MB 题面 题目描述 (题目译自 $JOI 2013 Final T3$「現代的な屋敷」) 你在某个很大的豪宅里迷路了.这个豪宅由东 ...
- 「题解」:$Six$
问题 A: Six 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 来写一篇正经的题解. 每一个数对于答案的贡献与数本身无关,只与它包含了哪几个质因数有关. 所以考虑二 ...
- 「题解」:$Smooth$
问题 A: Smooth 时间限制: 1 Sec 内存限制: 512 MB 题面 题面谢绝公开. 题解 维护一个队列,开15个指针,对应前15个素数. 对于每一次添加数字,暴扫15个指针,将指针对应 ...
- 「题解」:Kill
问题 A: Kill 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 80%算法 赛时并没有想到正解,而是选择了另一种正确性较对的贪心验证. 对于每一个怪,我们定义它的 ...
- 「题解」:y
问题 B: y 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 考虑双向搜索. 定义$cal_{i,j,k}$表示当前已经搜索状态中是否存在长度为i,终点为j,搜索过边 ...
- 「题解」:x
问题 A: x 时间限制: 1 Sec 内存限制: 256 MB 题面 题面谢绝公开. 题解 赛时想到了正解并且对拍了很久.对拍没挂,但是评测姬表示我w0了……一脸懵逼. 不难证明,如果对于两个数字 ...
随机推荐
- java.lang.ClassNotFoundException的解决方案
举一个特定的例子 java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSource 到Maven中央仓库下载 当我们看 ...
- thinkphp 5中的混合查询
1.手册样例thinkphp 5.0Db::table('think_user') ->where('name',['like','thinkphp%'],['like','%thinkphp' ...
- MySQL字段默认值设置详解
前言: 在 MySQL 中,我们可以为表字段设置默认值,在表中插入一条新记录时,如果没有为某个字段赋值,系统就会自动为这个字段插入默认值.关于默认值,有些知识还是需要了解的,本篇文章我们一起来学习下字 ...
- JS实现单例模式的多种方案
JS实现单例模式的多种方案 今天在复习设计模式中的-创建型模式,发现JS实现单例模式的方案有很多种,稍加总结了一下,列出了如下的6种方式与大家分享 大体上将内容分为了ES5(Function)与ES6 ...
- 各大搜索引擎 User-Agent
百度PC User-Agent Mozilla/5.0 (compatible; Baiduspider-render/2.0; +http://www.baidu.com/search/spider ...
- [论文阅读笔记] Fast Network Embedding Enhancement via High Order Proximity Approximati
[论文阅读笔记] Fast Network Embedding Enhancement via High Order Proximity Approximation 本文结构 解决问题 主要贡献 主要 ...
- BUAA-OO-第四单元总结——终章
面向对象第四单元博客总结--终章 第四单元作业设计 第13次作业设计 类和对应方法属性设计 类设计如下图所示 本次作业主要涉及六个类,其中包括主类 Main ,通用Map类 UmlElementIdM ...
- ES6学习-5 解构赋值(2)对象的解构赋值
啥也不说,先举个栗子: 1 let { myname, myage } = { myage: 18, myname: "郭郭" }; 2 console.log(myname) / ...
- centos下查看网卡,主板,CPU,显卡,硬盘型号等硬件信息
centos下查看网卡,主板,CPU,显卡,硬盘型号等硬件信息 rose_willow rose_willow 发布于 2016/06/16 11:32 字数 902 阅读 405 收藏 0 点赞 0 ...
- Linux下Shell实现服务器IP监测
实验室有一个服务器放在机房,装的是Ubuntu Server,IP为自动分配,因此一旦IP有变化就无法远程操作,必须去机房记录新的IP.学了几天Shell之后想,是不是可以定时检测其IP的变化,一旦有 ...