P8223题解
题解(moqueve)
我们定义一个数如果已经在自己最后的位置上,那么他的状态是 done;
我们考虑两种操作:
1、get,对于一个点,暴力地将其 done,一个数get代价约为
2、twin-swap,花
取 x=6:
* * 1 3 2 5 4 6 * *
move(1,6,1):
5 * * 1 3 2 4 6 * *
move(5,10,0):
5 * * 1 2 4 6 * * 3
move(1,6,0):
* * 1 2 4 5 6 * * 3
move(5,10,1):
* * 1 2 3 4 5 6 * *
3、double-swap,花
取 x=6:
* * * 1 3 2 5 4 6
move(3,8,1):
* * 4 * 1 3 2 5 6
move(4,9,1):
* * 4 6 * 1 3 2 5
move(3,8,0):
* * 6 * 1 3 2 4 5
move(4,9,0):
* * 6 1 3 2 4 5 *
move(1,6,1):
2 * * 6 1 3 4 5 *
move(4,9,1):
2 * * * 6 1 3 4 5
move(1,6,0):
* * * 6 1 2 3 4 5
move(4,9,0):
* * * 1 2 3 4 5 6
注:以上两条仅在一定条件下成立;
于是,我们考虑进行以下步骤:
对于较小的数据规模,我们选择
否则,我们选定一个偶数
首先我们前后依次 get,即先 get
然后对于中间的
如果存在两对逆序对,那我们直接用 twin-swap 交换即可;
否则,我们先用 double-swap 交换一对,此时:
- 如果没有逆序对了,则交换
h,h+1 ; - 如果还有逆序对,则交换这个逆序对;
如果操作到只剩最前面两个位置不对,我们对此 move(h,h+x-1,0),然后进行
这样差不多是
但是,我们发现这玩意在随机数据下优秀许多;
所以,我们可以在开始添加
我不知道怎么证明……但是我试了很多次都没超过
但是实际上我们还可以优化:
我们发现在随机后由于总体位置改变不大,所以每次移动
所以我们取
时间复杂度