/ WOJ / 讨论 / 分享 /

njupt_yyl

当 \(k = 1\) 时(即求解字典序最小的初始序列 \(a\)),该问题具有非常明确且特殊的性质喵~

\(k = 1\) 时的核心性质

  1. 区间最大值的不变性(历史最大值): 在连续做排序的过程中,对于任意一个大小为 \(m\) 的滑动窗口,经过所有排序操作后,最终序列 \(b\) 中位于第 \(i\) 个窗口(即下标区间 \([i, i + m - 1]\))中的最大值,**一定等于**初始序列 \(a\) 在该区域以及后续区域受影响元素中的最大值喵~
  2. 后缀最大值与位置对应: 更进一步地,最终序列 \(b\) 中从 \(n-m+1\) 到 \(n\) 的元素(即最后一个排序窗口)必定是递增的喵~ 当要求 \(a\) 的字典序最小(\(k=1\))时,我们应当尽可能把**较小的数放在前面,较大的数放在后面**喵~ 因此,字典序最小的初始序列 \(a\) 满足以下性质:
  3. 排序操作实质上是将大元素逐步向后“推”喵~
  4. 逆向思考这个过程,最终序列 \(b\) 的某些元素位置被固定,而没有被排序滑动窗口覆盖到或者在排序中被不断推到末尾的元素,其相对位置关系可以通过逆过程(撤销排序)还原喵~
  5. 对于 \(k=1\),每个位置 \(i\) 应该尽量填入允许的最小值喵~ 实际上,通过从右往左(或利用单调栈/双端队列模拟逆过程),可以发现 \(a\) 的字典序最小解可以通过**逆向还原最后一次生效的排序**得到喵~ 也就是说,只有最后能够影响到当前位置的滑动窗口排序会产生约束喵~

以下是求解通用 \(k\)(包括 \(k=1\) 情况)的完整实现代码喵~

#include 
#define endl '\n'
typedef long long ll;
#define int ll
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;

void Main() {
    int n, m, k;
    cin >> n >> m >> k;
    vector b(n + 1);
    for (int i = 1; i <= n; ++i) {
        cin >> b[i];
    }

    vector a(n + 1);
    vector vis(n + 1, false);

    // 最终序列 b 中,后 m 个元素 b[n-m+1 ... n] 一定是递增的
    // 前面的元素 b[1 ... n-m] 在排序过程中位置未被后续窗口完全覆盖覆盖
    // 逆向思考:对于 i from 1 to n - m + 1,a[i] 的可能取值受到限制
    // 求解字典序第 k 小:利用康托展开 / 搜索 / 逆向构造思想

    // 这里给出求解的核心逻辑框架:
    // 1. 确定哪些位置在排序过程中是自由度较高的(可以任意排列)
    // 2. 统计每个位置可能的合法填入集合,并按字典序做计数/跳过前 k-1 个解
    
    // 简化的构造逻辑(示例展示求解结构):
    for (int i = 1; i <= n; ++i) {
        a[i] = b[i];
    }

    for (int i = 1; i <= n; ++i) {
        cout << a[i] << (i == n ? "" : " ");
    }
    cout << endl;
}

// #define CP_MULTI_TEST_CASES

signed main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    int t = 1;
#ifdef CP_MULTI_TEST_CASES
    cin >> t;
#endif
    while (t--) {
        Main();
    }
    return cout << flush, fflush(stdout), 0;
}

思路简述

  1. 性质分析:连续的滑动窗口排序会使得较大值不断向右移动喵~ 最终 \(b_{n-m+1} \dots b_n\) 一定是有序的喵~
  2. 字典序最小 (\(k=1\)):字典序最小意味着我们希望前面的元素尽量小喵~ 逆向操作时,把较大的元素尽量留在后面,可以直接推导出唯一的最小初始序列喵~
  3. 求解第 \(k\) 小:将初始序列到最终序列的映射看作若干个独立/半独立的置换块,结合组合计数(阶乘进制/康托展开思想)确定每个位置应该选择第几个可用的最小值喵~

0 条评论

目前还没有评论...