Ordered Permutations

非常典型的 codeforces 小注意力题。

首先,我们发现当排列为 的正序数列时, 可以取到最大值。此时,。这是因为区间 的最小值为 ,共 个,区间 的最小值为 ,共 个,以此类推。

我们考虑如下构造过程。假设现在已经构造好了 的排列方式,考虑 可以插入到哪些位置。将 插入到已排好的内容中间,将会导致原先的许多区间贡献变得更小,不如将 放在头尾的位置更优。因此,最优排列的构造方案一定是从大往小,每次将当前的数放在头或尾的位置。

一共需决策 个数,每个数都有可能放在首尾两个位置,因此一共有 中方案。超出可以直接输出 -1。否则,对 进行二进制拆分,根据当前位的值决定该数应该放在头还是尾。可以直接 deque 维护。

#include <cstddef>
#include <deque>
#include <iostream>
using namespace std;
istream& fin = cin;
ostream& fout = cout;
using ui = unsigned int;
using uli = unsigned long long int;
using li = long long int;
int main(void) {
  ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  size_t T;
  fin >> T;
  while (T--) {
    size_t n;
    uli k;
    fin >> n >> k;
    --k;
    if (n - 1 < 64 && k >= (1ull << (n - 1))) {
      fout << "-1\n";
      continue;
    }
    deque<ui> ans{(ui)n};
    for (ui i = n - 1; i > 0; --i) {
      if (k & 1)
        ans.emplace_back(i);
      else
        ans.emplace_front(i);
      k >>= 1;
    }
    for (ui i : ans) fout << i << ' ';
    fout << '\n';
  }
  return 0;
}
posted @ 2024-12-17 16:30  MrPython  阅读(7)  评论(0)    收藏  举报  来源