poj.org/problem?id=3379
很好的一道考察智商/灵性的题,对于我这种老年选手难度挺大的,想了大半天才捋清思路
大概题意是
一个长度n的环,从第1的位置开始,每次往后数k个位置,并在第k个位置之后插入一个新的节点,新点的值为第k个位置点的值+1,然后以这个新节点开始重复,求操作m次后最后插入的节点的值
貌似是个反向的约瑟夫环,也确实是个反向约瑟夫环,但是如何反向操作呢?
环的结构,尤其是变化的环,很不友好,(就像绝对值函数一样,非线性不好处理,可以想办法转回为线性)
这里的思路是,把不断变化的环,展开成路径,每经过一个节点,或是插入一个新节点,相当于在前进路径上增加了一个节点, 用(i,d)表示路径上的节点,i表示初始环的索引,d表示当前节点的值与初始环上索引为i的点的值之间的增量,那么
1. 进行1此操作后,路径长度是1+(k+1), 操作m次后,路径长度是1+(k+1)*m, 所以一个长度为L的路径, 最多的操作数是(L-1)/(k+1) (路径长度可以是任意,所以最末位的点不一定是新增的点)
2. 一个长度为L的路径对应的环的长度为s=n+(L-1)/(k+1), 所以如果L>s则路径中的最后s个点就代表当前的环,把这s个点驱除后路径长度变为 L-s, 并且路径末尾点(i, d)中i保持不便,如果路径为L的末尾的点恰好是新增点,那么d-1,否则d也不变, 而只有当L=1+(k+1)*x (x>0)的时候,路径末尾点才会是新增点; 记录d发生变化的次数dd
这样不断进行反向操作,最后的路径就变成了满足L-(L-1)/(k+1) <= n的路径,这个路径的末尾节点(i, d) = L-(L-1)/(k+1)-1, L>1&&((L-1)%(k+1))==0, 最终的答案就是(i, d+dd)
举个例子
n=6, k=3, m=16, 反向环路径依次是
4: (5,0),(5,1),(5,1),(5,1),(0,0),(0,1),(0,1),(0,2),(1,0),(1,1),(1,1),(2,0),(2,1),(2,2),(3,0),(3,1),(3,2),(3,3),(3,3),(3,1),(4,0),(4,1),
3: (5,0),(5,1),(5,1),(0,0),(0,1),(0,2),(1,0),(1,1),(2,0),(2,1),(3,0),(3,1),(3,2),(3,3),(3,1),(4,0),
2: (5,0),(5,1),(0,0),(0,1),(1,0),(1,1),(2,0),(3,0),(3,1),(3,2),(3,1),(4,0),
1: (5,0),(0,0),(0,1),(1,0),(2,0),(3,0),(3,1),(3,1),(4,0),
0: (0,0),(1,0),(2,0),(3,0),(3,1),(4,0),
复杂度
整个处理过程的复杂度取决于反向处理的次数,每次处理掉(L-1)/(k+1)+n个点,总点数是1+(k+1)*m, 显然当n=1, k,m取最大值时,处理次数最多
根据题目给的范围 k<=10000, m<=1000000000, 可以通过程序计算出最多次数大约为~=213015, 比倍增的效果好
经验:把增环这个不容易直观分析的结构转化为路径这样可以简单处理的结构是个不错的思路