SOJ2506 规律题

来源:互联网 发布:win10电脑软件打不开 编辑:程序博客网 时间:2024/03/29 18:14

传送门:http://soj.me/2506

 

        好吧听了Q伟的话决定偶尔发一篇解题报告纪念某些个人觉得比较有意义的题目,要是以后忘了还可以来这边看一下。

        首先这是一个规律题,学LYC找规律就行了,当然没那么容易就找出来。

        直接对于两个数A,B,不妨先看A>>B的情况,这条数列会变成这样:

        A,B,A-B,A-2B,B,A-3B,A-4B,B,A-5B,A-6B,B,............

        就是说在A-kB大于零的时候,是很有规律的,都是A-kB,A-(k+1)B,B三项。但是显然当K足够大的时候就不满足了。

        假设A-kB>0,A-(k+1)B<0,后面那一项abs(2A-(2k+1)B)的符号难以确定,显然做不下去了。

        那我们可以换个角度来看,设A=tB+C,则C会出现在数列里,而且是最后一个可以表示成A-kB的大于等于0的数,再考虑上面的规律,每三项来看,C出现的位置可能会出现这样两种情况:

        B+C,B,C,B-C......

        B+C,C,B,B-C.....

        然后当出现C以后,对于第一种情况,我们可以令A'=B,B‘=C,然后又回到刚开始的情况:A',B’,A'-B‘,......

        对于第二种情况,我们令A'=B,B’=B-C,同样按照上面的方法继续做下去。

        这里我们可以看出来,这跟欧几里德求最大公约数的方法是非常相似的(第一种情况就是完全一样),我们每次只需要求出一个t和C,然后可以O(1)判断出所求的数是否在当前数列中存在。

        比较重要的一点是,对于第一种情况我们很容易可以看出,求到最后会变成gcd(A,B),实际对于第二种情况也是一样,因为gcd(A,B)=gcd(A-B,B)。所以必然存在到某个时刻有C=0,此时数列必然是这样gcd(A,B),gcd(A,B),0这三项循环出现,此时直接判断就好了。求欧几里德求最大公约数的复杂度为logN。

        总结起来大致流程是,当C不为0时,不断辗转相除,同时找所求项是否已经出现。如果当C等于0了仍未到达所求项,就直接对3取模然后判断就行了。(在计算C的位置的时候实际写起来还是有那么一点蛋疼的)

 

代码(微丑):

 

        这应该是我做的为数不多的规律题之一了吧,真不是我的菜。毛概课冒着被毛主席BS的危险搞出来的,毛主席真无敌。