1 条题解

  • 0
    @ 2025-11-4 15:55:08

    算法思路

    本题通过巧妙的区间查询来推断排列的相对顺序,核心思想是利用相邻区间的关系确定单调性。

    关键观察

    • 基础差值:b[i] = query(i-1, i) 得到相邻元素的绝对差值

    • 三角关系:c[i] = query(i-1, i+1) 帮助判断中间元素的相对位置

    • 单调性判断:通过比较 c[i-1] 与 b[i] + b[i-1] 的关系确定方向

    代码实现

    #include <bits/stdc++.h>
    #include "xylophone.h"
    using namespace std;
    
    const int $N = 5e3 + 5$, inf = 1e9;
    int a[$N$], n, b[$N$], c[$N$], ff[$N$];
    
    void solve(int n1) {
        n = n1;
    
        // 步骤1:获取相邻元素的绝对差值
        for (int i = 2; i <= n; i++)
            b[i] = query(i - 1, i);
    
        // 步骤2:获取三个连续元素的关系
        for (int i = 2; i < n; i++)
            c[i] = query(i - 1, i + 1);
    
        // 步骤3:确定单调性方向
        ff[2] = 1;  // 初始方向设为递增
        
        for (int i = 3; i <= n; i++) {
            if (c[i - 1] == b[i] + b[i - 1])
                ff[i] = 1;   // 保持同向
            else
                ff[i] = -1;  // 改变方向
        }
    
        // 步骤4:构建相对音高序列
        for (int i = 2, fx = 1; i <= n; i++) {
            fx *= ff[i];           // 累积方向
            a[i] = a[i - 1] + fx * b[i];  // 计算相对音高
        }
    
        // 步骤5:归一化到 $[1, n]$ 范围
        int mn = inf;
        for (int i = 1; i <= n; i++)
            mn = min(mn, a[i]);
    
        for (int i = 1; i <= n; i++)
            a[i] -= mn - 1;
    
        // 步骤6:检查音高 $1$ 和 $N$ 的相对位置
        int x = 0, y = 0;
        for (int i = 1; i <= n; i++) {
            if (a[i] == 1) x = i;
            else if (a[i] == n) y = i;
        }
    
        // 步骤7:如果顺序不对则反转
        if (x > y) {
            for (int i = 2, fx = -1; i <= n; i++) {
                fx *= ff[i];
                a[i] = a[i - 1] + fx * b[i];
            }
    
            mn = inf;
            for (int i = 1; i <= n; i++)
                mn = min(mn, a[i]);
    
            for (int i = 1; i <= n; i++)
                a[i] -= mn - 1;
        }
    
        // 步骤8:输出答案
        for (int i = 1; i <= n; i++)
            answer(i, a[i]);
    }
    

    算法步骤详解

    1.数据收集

    • b[i]:相邻元素 i1i-1ii 的音高差绝对值

    • c[i]:三个连续元素 i1i-1, ii, i+1i+1 的极差

    2.单调性判断

    对于位置 ii

    • 如果 c[i1]=b[i]+b[i1]c[i-1] = b[i] + b[i-1],说明 iii1i-1 同向变化

    • 否则说明方向改变

    3.序列构建

    从位置 22 开始,根据方向因子 ff[i] 累积计算相对音高:

    或者更精确地表示为:

    其中 fx\text{fx} 是累积的方向因子,取值为 +1+11-1

    4.范围调整

    将相对音高平移到 [1,n][1, n] 范围内。

    5.顺序验证

    确保音高 11 在音高 NN 的左边,否则反转整个序列。

    复杂度分析

    • 查询次数:(n1)+(n2)=2n3(n-1) + (n-2) = 2n-3

    • 时间复杂度:O(n)O(n)

    • 空间复杂度:O(n)O(n)

    正确性证明

    1. 该算法基于以下关键性质:

    2. 相邻差值确定了元素间的相对距离

    3. 三元素查询揭示了单调性变化

    题目保证音高 11 在音高 NN 的左边,为最终调整提供了依据

    算法在 2n32n-3 次查询内必定能确定整个排列,满足题目要求的 1000010000 次查询限制(n5000n \leq 5000)。

    • 1

    信息

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