题解:P16414 【MX-X28-T3】「FAOI-R12」寄清梦
Sunrise_up · · 题解
赛时想的
求点赞 qwq!
思路
以下所有数字的二进制位从第
条件的式子有些难搞,于是考虑变换一下式子,将
若假定
同理若
所以条件变为
研究这个条件,发现满足这个条件需要相邻两数中较小的数二进制下某一位是
所以当
首先考虑构造
考虑二进制后两位的排布规律,尝试每
容易想到将奇偶数交替,即
同理可以想到
我们使用将奇偶数交替的构造,发现这样放的话后面还有
- 当
n\bmod 4=0 时,不管,已经放完。 - 当
n\bmod 4=1 时,留下一个n ,直接放在序列末端即可,前一个数是n-2 ,后两位为11 ,n 的后两位为01 ,n 较大,它们的第1 位满足。 - 当
n\bmod 4=2 时,留下n-1 和n ,随便你怎么放,前面一个数是n-3 ,证明同理。 - 当
n\bmod 4=3 时,留下三个数n-2,n-1 和n ,不好搞,可以在后面随便放n-2 和n-1 ,但是n 要找另外的地方放,直接枚举。或者不枚举,我们可以找到n 二进制下最小的为0 的位数,假设是第m 位,那么直接插在2^m+2 后面即可,即2^m+2 和2^m+1 之间。此时2^m+2 一定存在,下面给出证明。
:::info[证明:当
显然
- 若
t=0 : 则n = 2^m - 1 。 这是二进制全1 的形式,属于n=2^k-1 无解情况,早已提前输出-1 ,不会进入构造环节。
综上,假设不成立。故必有:
当
所以
:::
代码
时间复杂度
代码中 (~n)&-(~n) 其实就是用 lowbit 的技巧来求最低位的
#include<bits/stdc++.h>
using namespace std;
int T,n;
signed main(){
ios::sync_with_stdio(0);cin.tie(0);
cin>>T;
while(T--){
cin>>n;
if(!(n&(n+1))&&n>=3){
cout<<"-1\n";
continue;
}
for(int i=1;i<=n-(n&1);i+=2){
if(n%4==3&&((~n)&-(~n))==i-1)cout<<i+1<<' '<<n<<' '<<i<<' ';
else cout<<i+1<<' '<<i<<' ';
}
if(n%4==1)cout<<n<<' ';
cout<<'\n';
}
}