首先考虑什么时候 i & pi == 0 很显然的一点是当 pi == i ^ t (这里 t 代指一个二进制全为 1 的数)时成立
那么由此得知当 n 为 2 的幂的时候只需要不断地首尾交换数值就够了,而我们进一步的分析上面的条件可以发现如
果将对应 i 的 0 位的数值换为 1 也是可以的,所以可以将后面的大数(高位有 1 的数)向前调整,就可以把高位
的影响给消除。
综上所述,我们可以进行最高位的二进制进行划分,把所有的最高位的二进制以上的值向下调整,然后将二进制内的
数进行前后调整,再递归处理后面多余的数即可。
#include<bits/stdc++.h>usingnamespace std;#define_for(i, a, b)for(int i = a; i <= b; i ++)int n;int a[500009];voiddfs(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);/// 递归处理}intmain(){
cin >> n;_for(i,0, n -1) a[i]= i;dfs(0, n);_for(i,0, n -1)printf("%d ", a[i]);return0;}
思维(构造)首先考虑什么时候 i & pi == 0 很显然的一点是当 pi == i ^ t (这里 t 代指一个二进制全为 1 的数)时成立 那么由此得知当 n 为 2 的幂的时候只需要不断地首尾交换数值就够了,而我们进一步的分析上面的条件可以发现如果将对应 i 的 0 位的数值换为 1 也是可以的,所以可以将后面的大数(高位有 1 的数)向前调整,就可以把高位的影响给消除。 综上所述,我们可以进行最高位的二进制进行划分,把所有的最高位的二进制以上的值向下调整,然后将二进制内的数