#include<iostream>
using namespace std;
int main()
{
int t;
cin >> t;
while(t --)
{
int n;
cin >> n;
int k = 0;
while((1 << (k + 1)) <= n - 1) k ++; //防止越位的边界小技巧
for(int i = (1 << k) - 1; i >= 0; i --)
cout << i << ' ';
for(int i = (1 << k); i < n; i ++)
cout << i << ' ';
cout << endl;
}
return 0;
}
这个题要求的异或最大值,我们设k是n - 1的最高位1的所在位数,所以这个最大值至少肯定是2的k次幂(总有一个k位1消不掉,他和其他的k位0异或都是1)。那么如何摆(贪心)使得我们可以摆出2的k次幂呢?首先我们知道最高位是1的数相互异或肯定能把高位1消掉,但是总有一个高位1消不掉,那么这个高位1我们可以把它认作2的k次幂,并且将它与0一起放,这样就保证了最大异或值是2的k次幂,至于小于2的k次幂的数,他们的高位都是0,把他们放到一起异或,既不会产生高位1,同时xor的结果也不会越过高位1。所以摆法就是将小于2的k次幂的数放一起,大于等于2的k次幂的数放一起,中间隔个0。见代码!