#L3174. 「IOI2017」古书

「IOI2017」古书

题目描述

很抱歉,由于技术局限,本题仅支持各版本 C++。

提示:请参考选手目录下的示例代码,int[] 的实际实现方式为 std::vector<int>int64 的实际实现方式为 long long

德黑兰市是伊朗国家图书馆的所在地。这个图书馆的镇馆之宝位于一个长长的大厅内,大厅里有排成一行的 nn 张桌子,从左到右依次编号为从 00n1n-1。每张桌子上都陈列着一本手写的古书。这些古书是根据其历史年份进行排序的,这使得访客们难以根据书名来查找它们。所以,图书馆主管决定按照书名的字母序来重新排列它们。

图书管理员 Aryan 要完成这项工作。他创建了一个长度为 nn 的列表 pp,其中包括由 00n1n-1 的不同整数。这个列表描述了按字母序来重排古书所要做的改变:对于 0i<n0 \le i < n,目前在桌子 ii 上的古书应该被移到桌子 p[i]p[i] 上。

Aryan 从桌子 ss 开始重排这些古书。他希望在做完重排工作之后再回到同一张桌子上。由于这些古书非常珍贵,在任何时间,他手持的古书都不能超过一本。在重排古书的过程中,Aryan 将会做一系列的操作。每个操作只能是以下其中之一:

  • 如果他手上没有书,而他所在的桌子上恰好有一本书时,他可以拿起这本书。
  • 如果他手上有一本书,而他所在的桌子上恰好有另一本书时,他可以把手上的书和桌子上的书进行交换。
  • 如果他手上有一本书,而他所在的桌子上没有书时,他可以把手上的书放到这个桌子上。
  • 他可以走到任何一张桌子前。当他进行这个操作时,他手上可以拿一本书。

对于所有 0i,jn10 \le i,j \le n-1,桌子 ii 和桌子 jj 之间的距离正好是 ji|j-i| 米。你的任务是,计算出 Aryan 重排好所有古书所走过的总距离的最小值。


实现细节

你需要实现下面的函数:

int64 minimum_walk(int[] p, int s)

pp 是一个长度为 nn 的数组。初始阶段在桌子 ii 上的古书需要被 Aryan 移到桌子 p[i]p[i] 上(对于所有 0i<n0 \le i < n)。

ss 是初始阶段 Aryan 所在桌子的编号,同时也是重排好所有古书之后他应该在的位置。

该函数要返回 Aryan 重排好所有古书所需走过的总距离的最小值(以米为单位)。


例子

minimum_walk([0, 2, 3, 1], 0)

在这个例子中,n=4n=4,在初始阶段 Aryan 位于桌子 00 处。他按照如下步骤进行重排:

  1. 走到桌子 11 处并且拿起桌上的书。这本书应该要被放到桌子 22 上。
  2. 然后,他走到桌子 22 处,并且把他手上的书和桌子上的书进行交换。现在他新拿到手上的书应该被放到桌子 33 上。
  3. 然后,他走到桌子 33 处,并且把他手上的书和桌子上的书进行交换。现在他新拿到手上的书应该被放到桌子 11 上。
  4. 然后,他走到桌子 11 处,并且把他手上的书放到桌子上。
  5. 最后,他回到桌子 00 处。

注意,桌子 00 上的书已经在正确的位置,即桌子 00 上,因此 Aryan 不需要把它拿起来。在这个方案中,他的总行走距离是 66 米。这是一个最优解;因此,函数应该返回 66


限制与子任务

  • 1n10000001 \le n \le 1\,000\,000
  • 0sn10 \le s \le n-1
  • 数组 pp 包含 nn 个从 00n1n-1(含)的不同整数。

子任务编号及附加限制如下:

  1. 1212 分)n4n \le 4s=0s=0
  2. 1010 分)n1000n \le 1000s=0s=0
  3. 2828 分)s=0s=0
  4. 2020 分)n1000n \le 1000
  5. 3030 分)没有附加任何限制

评测工具示例

评测工具示例将会读取如下格式的输入数据:

第 1 行:n s
第 2 行:p[0] p[1] ... p[n-1]

评测工具示例将输出一行,其中包括 minimum_walk 的返回值。