其他分享
首页 > 其他分享> > [ AtCoder Grand Contest 031] C - Differ by 1 Bit (分治)

[ AtCoder Grand Contest 031] C - Differ by 1 Bit (分治)

作者:互联网

Problem

题目地址

Solution

前置

题解

考虑用分治法构造一组解。设原问题为 \(f(A,B,s)\),\(s\) 是一个\(01\)序列,表示二进制下可以调整的位,其中\(0\)表示不可调整,\(1\)表示可以调整,原问题的 \(s\) 是一个长度为 \(n\) 的全为 \(1\) 的序列。

假设 \(A,B\) 第 \(x\) 位是不同的,那么固定第 \(x\) 位,使得构造的解左半部分第 \(x\) 位全和 \(A\) 相同,右半部分第 \(x\) 位全和 \(B\) 相同,此时 \(s'\) 将在原 \(s\) 的基础上将第 \(x\) 位修改为\(0\)。将 \(A\) 剩下可以调整的任意一位修改,令其为 \(mid\)。则原问题就变成了 \(f(A,mid,s')\) 和 \(f(mid,B,s')\)。注意 \(mid->B\) (也就是右半部分)\(mid\) 的第 \(x\) 位也要和 \(B\) 一样。

Code

Talk is cheap.Show me the code.

#include<bits/stdc++.h>
using namespace std;
inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while(ch<'0' || ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { x=(x<<3)+(x<<1)+(ch^48); ch=getchar(); }
    return x * f;
}
int n,A,B;
int Calc(int x) {
	if(x==0) return 0;
	int res = 0;
	while(x) {
		++res; x -= x&-x;
	}
	return res;
}
void Dfs(int a,int b,int s) {
	if(s) {
		int x = (a^b) & s; x = x & -x;
		s ^= x;
		int mid = a ^ (s & -s);
		Dfs(a,mid,s); Dfs(mid^x,b,s);
	} else printf("%d ",a);
}
int main()
{
	n = read(); A = read(); B = read();
	if(Calc(A^B) & 1) {
		puts("YES"); Dfs(A,B,(1<<n)-1);
	} else puts("NO");
    return 0;
}
/*
2 1 3

YES
1 0 2 3
*/

Summary

标签:AtCoder,Differ,ch,分治,Contest,二进制,奇数,mid,位数
来源: https://www.cnblogs.com/BaseAI/p/13960215.html