P9185 [USACO23OPEN] Rotate and Shift B 题解

· · 题解

还没有人发题解,我来一发。

Sol

设原序列为 B

令操作 C 为将 B_{A_1} 挪至 B_{A_2},将 B_{A_2} 挪至 B_{A_3}\ldots,将 B_{A_n} 挪至 B_{A_1}

令操作 -x 为将序列逆时针转 x 次,即 B_1 \to B_2B_2 \to B_3\ldotsB_n \to B_1

令操作 +x 为将序列顺时针转 x 次。

重点来了:

我们可以把将 A 向后挪再进行 C 操作想成先将 B 逆时针转 1 次,然后进行 C 操作,然后再顺时针转回去

当然每次转的次数不同,例如进行两次将 A 向后挪再进行 C 操作,我们就需要逆时针转 2 次,然后进行 C 操作,然后再顺时针转回去

则操作为:

C,-1,C,+1,-2,C,+2,-3,C,+3,\ldots,-(n-1),C,n-1

其中 +- 可以抵消,抵消后结果为:

C,-1,C,-1,C,-1,\ldots,C,-1,C,n-1 C,-1,C,-1,C,-1,\ldots,C,-1,C,-1,n

我们称 C,-1D 操作

我们创建数组 jmp[i][j],其中 jmp[i][j]=d 表示进行 2^jD 操作把 b_i 挪到了 d 位置。

通过倍增,原始暴力的复杂度 O(nT) 成功优化到 O(n\log_{2}{T}),复杂度显然可以通过本题。

最后不要忘了顺时针转 n 次,这道题目就做出来了。

代码

一些忠告:

  1. 最后不要忘了顺时针转 n 次。
  2. 本人代码 31 行,y 很大,需要取模,否则会变成负数(赛时被卡)。
  3. 请不要抄题解。