loj#P3174. 「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)

IOI2017-books-desc.png

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

  • 走到桌子 11 处并且拿起桌上的书。这本书应该要被放到桌子 22 上。
  • 然后,他走到桌子 22 处,并且把他手上的书和桌子上的书进行交换。现在他新拿到手上的书应该被放到桌子 33 上。
  • 然后,他走到桌子 33 处,并且把他手上的书和桌子上的书进行交换。现在他新拿到手上的书应该被放到桌子 11 上。
  • 然后,他走到桌子 11 处,并且把他手上的书放到桌子上。
  • 最后,他回到桌子 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 分)没有附加任何限制

评测工具示例

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

  • 11 行:n sn~s
  • 22 行:p[0] p[1]  p[n1]p[0]~p[1]~\cdots~p[n-1]

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