洗牌问题

设2n张牌分别标记为1, 2, ..., n, n+1, ..., 2n,初始时这2n张牌按其标号从小到大排列。经一次洗牌后,原来的排列顺序变成n+1, 1, n+2, 2, ..., 2n, n。即前n张牌被放到偶数位置2, 4, ..., 2n,而后n张牌被放到奇数位置1, 3, ..., 2n-1。可以证明对于任何一个自然数n,经过若干次洗牌后可恢复初始状态。现在你的的任务是计算对于给定的n的值(n≤105),最少需要经过多少次洗牌可恢复到初始状态。

首先,朴素的做法自然是模拟一遍。时间复杂度$\text{O}\left( n^2\right)$。对于这个数据范围$n \le 100000$是过不了的。

再手算几个数据。。。发现只要①回了原位,其它都回了原味。那么只需要模拟①的位置即可。

自然,你会想,这又是为什么呢?

注意到原先在第$x$位上的数变换一次后变成$2x$或$(x-n)\cdot 2 - 1 = 2x-2n-1$位,即$2x \mod \left( 2n+1\right)$,而求余运算对于乘法来说,$\left( a \cdot c\right) \mod b = ( a \mod b ) \cdot ( c \mod b ) \mod b $,于是我们要求的就是最小的一个$t$使得$x\cdot 2^t \equiv x \pmod{2n+1}$。

当$x = 1$时(即对①进行模拟),我们得到了一个符合$x = 1$的$t$ (略废话),即$2^t \equiv 1 \pmod{2n + 1}$,等式两边同时乘上$d$,得$d\cdot 2^t \equiv d \pmod{2n+1}$,对比形式,我们便证明了模拟①算法的正确性。

 

posted @ 2014-08-22 15:19  zball  阅读(502)  评论(3编辑  收藏  举报