1 条题解

  • 0
    @ 2025-10-19 23:03:25

    详细题解:

    问题分析

    题目需要处理两个问题:

    1. 找到从哪个城市出发,小A与小B行驶路程比值最小
    2. 回答多组查询,计算从指定城市出发在距离限制内的行驶路程

    算法思路

    1. 预处理最近邻信息

    代码使用链表+排序的方法为每个城市找到"最近"和"第二近"的城市:

    • 首先对所有城市按海拔排序
    • 使用双向链表维护城市关系
    • 对于每个城市,比较左右相邻城市确定最近和第二近城市
    • 处理完后从链表中删除当前城市

    2. 倍增预处理

    构建倍增数组 bz[i][j][k]

    • bz[i][j][1]:从城市i出发,走2^j步,小A行驶的总距离
    • bz[i][j][2]:从城市i出发,走2^j步,小B行驶的总距离
    • bz[i][j][3]:从城市i出发,走2^j步后到达的城市

    状态转移:

    bz[j][i][1] = bz[j][i-1][1] + bz[bz[j][i-1][3]][i-1][1];
    bz[j][i][2] = bz[j][i-1][2] + bz[bz[j][i-1][3]][i-1][2];
    bz[j][i][3] = bz[bz[j][i-1][3]][i-1][3];
    

    3. 查询处理

    使用倍增法快速回答查询:

    • 从高位到低位尝试跳跃
    • 如果跳跃后总距离不超过限制,则累加距离并更新位置
    • 最终得到小A和小B的行驶距离

    代码关键部分

    排序预处理

    使用希尔排序对城市按海拔排序,同时维护原始编号映射:

    for(i=1;i<=11;i++)
        for(j=t[i]+1;j<=n;j++){
            jj=j;
            while(jj-t[i]>0&&h[jj]<h[jj-t[i]]){
                // 交换海拔和编号映射
                tt=h[jj]; h[jj]=h[jj-t[i]]; h[jj-t[i]]=tt;
                tt=xq[jj]; xq[jj]=xq[jj-t[i]]; xq[jj-t[i]]=tt;
                tt=xp[xq[jj]]; xp[xq[jj]]=xp[xq[jj-t[i]]]; xp[xq[jj-t[i]]]=tt;
                jj=jj-t[i];
            }
        }
    

    最近邻计算

    for(i=1;i<=n;i++){
        aa = h[l[l[xp[i]]]];  // 左左邻居
        bb = h[l[xp[i]]];     // 左邻居  
        cc = h[r[xp[i]]];     // 右邻居
        dd = h[r[r[xp[i]]]];  // 右右邻居
        
        // 根据距离规则确定minn[i]和minnn[i]
        // ...
        
        // 从链表中删除当前城市
        r[l[xp[i]]] = r[xp[i]];
        l[r[xp[i]]] = l[xp[i]];
    }
    

    倍增查询

    for(j=log2(n);j>=0;j--)
        if(disa+disb+bz[mmm][j][1]+bz[mmm][j][2]<=x[i]){
            disa = disa + bz[mmm][j][1];
            disb = disb + bz[mmm][j][2];
            mmm = bz[mmm][j][3];
        }
    

    复杂度分析

    • 预处理O(nlogn)O(n \log n) 排序 + O(nlogn)O(n \log n) 倍增预处理
    • 查询O(mlogn)O(m \log n),每组查询 O(logn)O(\log n)

    算法优势

    使用倍增法将每次查询的时间复杂度从O(n)O(n)优化到O(logn)O(\log n),能够处理n=105n=10^5m=104m=10^4的大数据规模。

    • 1

    信息

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