Solving this requires making the observation that only swaps between adjacent elements are allowed, and all of these swaps must be disjoint. This can be discovered by writing a brute force program, or just noticing the pattern for small n.
Here's a proof for why this is. Consider the cycle that contains n. Since n is the largest number, it must be the last cycle in the sequence, and it's the first element of the sequence. If this cycle is length 1, then we're obviously ok (we can always append (n) to the end). If the cycle is of length 2, we need n to be involved in a cycle with n - 1. Lastly, if the cycle is of length 3 or more, we will see we run into a problem. We'll only show this for a cycle of length 3 (though this argument does generalize to cycles of larger length). Let (nxy) be the cycle. So that means, n is replaced by x, x is replaced by y and y is replaced by n. So, in other words, the original permutation involving this cycle must look like
position: ... y x n
number : ... n y x
However, we need it to look like (nxy) so this case is impossible.
So, once we know that n is a in a cycle of length 1 or 2, we can ignore the last 1 or 2 elements of the permutation and repeat our reasoning. Thus, the only valid cases are when we swap adjacent elements, and all swaps are disjoint. After making this observation, we can see the number of valid permutations of length n is fib(n+1). (to see this, write try writing a recurrence).
To reconstruct the kth permutation in the list, we can do this recursively as follows: If k is less than fib(n), then 1 must be the very first element, and append the kth permutation on {1,...,n-1} with 1 added everywhere. Otherwise, add 2, 1 to the very front and append the k-fib(n)th permutation on {1,...,n-2} with 2 added everywhere.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fib[100];
int main(int argc, char const *argv[])
{
ll n,k;
fib[0] = fib[1] = 1;
for(int i = 2; i <= 50; i++) fib[i] = fib[i-1] + fib[i-2];
while(cin>>n>>k) {
int now = 1;
while(now <= n) {
if(fib[n-now] < k) {
k -= fib[n - now];
printf("%d %d ", now+1,now);
now += 2;
}else {
printf("%d ",now);
now += 1;
}
}
printf("\n");
}
return 0;
}