>Link
luogu P1081
ybtoj开车旅行
>Description
>解题思路
先预处理 n n n个点,从每一个点出发,最近的下个点和第二近的下个点
因为距离为两点的海拔高度差,那我们就可以先按照海拔高度排个序,那最近的点就在它的前驱和后驱之中,第二近的点就在前驱、后驱、前驱的前驱、后驱的后驱之中
那我们从 1 1 1到 n n n处理完一个点后,要把当前点删去,因为题目规定了后面的点不能到达前面的点
这个可以用双向链表维护,也可以用平衡树
(要注意是否越界QwQ)
对于第二个问题,由于必须先有一个 O ( n ) O(n) O(n),所以我们往 O ( n l o g n ) O(nlogn) O(nlogn)考虑
设两个数组倍增DP:
f i , j , 0 / 1 f_{i,j,0/1} fi,j,0/1:从第 i i i个点出发,走 2 j 2^j 2j步,小A / 小B 先走最后到达的终点
d i s i , j , 0 / 1 dis_{i,j,0/1} disi,j,0/1:从第 i i i个点出发,走 2 j 2^j 2j步,小A先走,小A / 小B走过的路程
然后我们DP就行了(转移方程还挺好推得,就设置状态不会QAQ)
然后我们按照题意处理就行了,最多走 x x x路程,那我们就倍增跳着走,在 x x x的限制下尽量走多的路程
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include