[ICPC 2024 Kunming I] 乐观向上题解
题目描述
求字典序最小的序列 p0,p1,p2⋯,pn−1,该序列是 0,1,2,⋯,(n−1) 的一个排列,且满足以下限制:对于所有 0≤i<n,都有 p0⊕p1⊕⋯⊕pi>0。这里 ⊕ 是按位异或运算。
称一个长度为 n 的序列 p0,p1,⋯,pn−1 的字典序小于另一个长度为 n 的序列 q0,q1,⋯,qn−1,若存在一个整数 0≤k<n 使得对于所有 0≤i<k 有 pi=qi,以及 pk<qk。
输入格式
有多组测试数据。第一行输入一个整数 T 表示测试数据组数。对于每组测试数据:
第一行输入一个整数 n(1≤n≤106)。
保证所有数据 n 之和不超过 106。
输出格式
每组数据输出一行 n 个由单个空格分隔的整数,表示字典序最小的且满足限制的排列。如果不存在这种排列,输出 impossible。
输入输出样例
输入 #1复制
4 1 2 3 4
输出 #1复制
impossible 1 0 1 0 2 impossible
思路
贪心。
代码见下
#include<bits/stdc++.h>
using namespace std;
long long t,n,k,a[1000006],m,b[1000006],c[1000006],d[1000006],lk=0,sd=0;
int main(){
cin>>t;
while(t--){
cin>>n;
if(n!=1){
for(int i=0;i<=n-1;i++){
b[i]=0;
c[i]=i+1;
d[i]=i-1;
a[i]=-1;
}
sd=0;
a[n]=-1;
d[0]=0;
a[1]=1;
b[1]=1;
c[0]=2;
d[2]=0;
lk=1;
for(int i=2;i<=n;i++){
for(int j=0;j<=n-1;j=c[j]){
if(j!=lk&&b[j]==0){
a[i]=j;
lk^=j;
c[d[j]]=c[j];
d[c[j]]=d[j];
b[j]=1;
break;
}
}
if(a[i]==-1){
sd=1;
break;
}
}
if(sd==1){
cout<<"impossible"<<endl;
}
else{
for(int i=1;i<=n;i++){
cout<<a[i]<<" ";
}
cout<<endl;
//break;
}
}
else{
cout<<"impossible"<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号