牛客/20328/A Minimum Cost Perfect Matching 题解

思维(构造)

首先考虑什么时候 i & pi == 0 很显然的一点是当 pi == i ^ t (这里 t 代指一个二进制全为 1 的数)时成立
	
那么由此得知当 n 为 2 的幂的时候只需要不断地首尾交换数值就够了,而我们进一步的分析上面的条件可以发现如
果将对应 i 的 0 位的数值换为 1 也是可以的,所以可以将后面的大数(高位有 1 的数)向前调整,就可以把高位
的影响给消除。
	
综上所述,我们可以进行最高位的二进制进行划分,把所有的最高位的二进制以上的值向下调整,然后将二进制内的
数进行前后调整,再递归处理后面多余的数即可。
#include <bits/stdc++.h>
using namespace std;

#define _for(i, a, b) for(int i = a; i <= b; i ++) 

int n;
int a[500009];

void dfs(int x, int p) {  /// x 是起点, p 是还需要划分的空间
    if(p == 0) return ;
    int t = 1;
    while(t <= p) {
        t = t << 1;
    }   t >>= 1;
    int l = x, r = x + t - 1;
    _for(i, x + t, x + p - 1) {  /// 进行前后的交换
        swap(a[i], a[i - t]);
    }
    while(l < r) {  /// 进行二进制内的交换
        swap(a[l ++], a[r --]);
    }
    dfs(x + t, p - t);  /// 递归处理
}
int main() {
    cin >> n;
    _for(i, 0, n - 1) a[i] = i;
    dfs(0, n);
    _for(i, 0, n - 1) printf("%d ", a[i]);
    return 0;
}
本题知识点:递归、二进制、思维
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值