• [ AtCoder Grand Contest 031] C


    Problem

    题目地址

    Solution

    前置

    题解

    • 结论1:有解必要条件(A)(B) 在二进制下不同的位数是奇数。

    • 结论2:(A)(B) 在二进制下不同的位数是奇数,那么就可以构造出一组解。换言之,(A)(B) 在二进制下不同的位数是奇数,是有解充分条件

    考虑用分治法构造一组解。设原问题为 (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

    • 根据题目猜想出一些结论。

    • 二进制问题考虑分治思想

  • 相关阅读:
    Docker--简介&&安装
    Mycat
    Mysql--主从复制
    Nginx--平滑升级
    Nginx--rewrite
    Nginx--缓存
    Mysql--SQL语句
    Nginx--虚拟主机
    Nginx--反向代理&&负载均衡
    Nginx--用户认证&&访问控制&&限速&&状态访问
  • 原文地址:https://www.cnblogs.com/BaseAI/p/13960215.html
Copyright © 2020-2023  润新知