题目要求构造,但是关于构造很难找到规律,于是在笔者上课列了一堆数据后发现对于一个排列存在一种“环”,一个位置的值指向下一个的地址

现有一个排列[4,3,2,1]其中a1=4,a4=1;a2=3,a3=2;这里存在两个含有2个元素的环,

对于其他排列[4,1,2,3]其中a1=4,a4=3,a3=2,a2=1;这里存在一个含有4个元素的环;

每一个环中重排的代价是环内元素个数-1

而一个排列重排的代价就是所有环的代价之和

通过环的计算不难发现,k至少为n/2(若n为奇数则k至少为n/2-1),至多为n-1

最简单的构造方式就是交换相邻元素,如果是奇数则特殊判断,对最后三个元素交换,就能得到一个重排代价最小的排列

注意到两个环合并之后总代价会增加1,根据这个性质我们只需要合并环,直到代价为k

#include <iostream>
#include <vector>
#define ll long long 
using namespace std;

int main() {
    ll n,k;cin>>n>>k;
    vector<ll>a(n+1);
    ll kc=0;
    for(int i=2;i<=n;i+=2){
        a[i]=i-1;
        a[i-1]=i;
        kc++;
    }
    if(a[n]==0){
        a[n]=n-2;
        a[n-1]=n;
        kc++;
    }
    if(kc>k||k>=n){
        cout<<-1<<endl;
        return 0;
    }
    for(int i=3;i<=n&&kc<k;i+=2,kc++){
        swap(a[i],a[i-1]);
    }
    for(int i=1;i<=n;i++){
        cout<<a[i]<<" ";
    }
    cout<<endl;
}