1 条题解

  • 0
    @ 2026-5-5 13:33:38

    题意简述

    给定 n,m,kn, m, km<km < k),构造一个 1n1 \sim n 的排列 pp,定义:

    • f(i)f(i) = 前缀 p[1..i]p[1..i] 中所有 k\ge k 的元素之和;
    • g(i)g(i) = 前缀 p[1..i]p[1..i] 中所有 m\le m 的元素之和。

    最大化 i=1nf(i)i=1ng(i)\sum_{i=1}^n f(i) - \sum_{i=1}^n g(i),输出任意一个能取到最大值的排列。

    贡献分析

    对于排列中的每个元素 xx,若它位于位置 pospos(从 11 开始),它会出现在所有 iposi \ge pos 的前缀中。因此:

    • xkx \ge k,它对 f\sum f 的贡献为 x(npos+1)x \cdot (n - pos + 1)
    • xmx \le m,它对 g\sum g 的贡献为 x(npos+1)x \cdot (n - pos + 1)(在差值中贡献为负);
    • m<x<km < x < k,则对两个和都没有贡献。

    总差值 $D = \sum_{x \ge k} x \cdot w(pos) - \sum_{y \le m} y \cdot w(pos)$,其中权重 w(pos)=npos+1w(pos) = n - pos + 1 随位置靠前增大。

    最大化策略

    根据排序不等式,要使正项最大,应该让更大的 xx 搭配更大的权重(更靠前的位置),即把所有 k\ge k 的数按降序放在序列的最前面。

    要使负项(减去 ywy \cdot w)尽可能小(即整体差值更大),应该让更小的 yy 搭配较大的权重,或者等价地,把所有 m\le m 的数按升序放在序列的最后面(这样较小的 yy 会相对靠前,权重稍大,但整体求和更小;详细推导见附注)。位于 mmkk 之间的数字可以任意放置。

    因此构造方案如下:

    1. 先输出所有 k\ge k 的数,从大到小;
    2. 再输出所有满足 m<x<km < x < k 的数,顺序任意;
    3. 最后输出所有 m\le m 的数,从小到大。

    可以证明该构造能取到理论最大差值。

    附注:坏数排序的简易证明

    设两个坏数 a<ba < b,两个权重 w1>w2w_1 > w_2(靠前权重大)。分配方案:

    • 方案一:aw1+bw2a \cdot w_1 + b \cdot w_2
    • 方案二:aw2+bw1a \cdot w_2 + b \cdot w_1

    方案一减去方案二 =(ab)(w1w2)<0= (a-b)(w_1-w_2) < 0,故方案一的和更小。因此在坏数区域内,按升序排列(小的相对靠前)能使负项之和最小。

    时间复杂度 O(n)O(n),总复杂度 O(n)O(\sum n),满足要求。

    参考代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int n, m, k;
        cin >> n >> m >> k;
    
        // 第一部分:>= k 的数降序
        for (int i = n; i >= k; --i)
            cout << i << ' ';
    
        // 第二部分:m < x < k 的数,任意顺序
        for (int i = m + 1; i < k; ++i)
            cout << i << ' ';
    
        // 第三部分:<= m 的数升序
        for (int i = 1; i <= m; ++i)
            cout << i << ' ';
    
        cout << '\n';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
        int t;
        cin >> t;
        while (t--) solve();
        return 0;
    }
    
    • 1

    信息

    ID
    6892
    时间
    2000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者