递推式循环节

前天晚上去acdream群赛找虐,看到一道斐波那契数列的题,就是要求循环节

第一反应是想到博客里某个人发的一篇 Fib数模n的循环节 ,想都没想直接拷过来交了一发,Wa了,看不懂的代码还是懒得改,于是放弃了

第二反应是想到了 Fibonacci Returns  这个题是求 Fib(C(n,r))%p ,代码可以看这里,也是要求循环节,然后把整个代码拷过来,改了改,交了一发超时了

呵呵,尼玛,感觉这半年差不多废了,啥都不会了

然后在解题报告里,学到了新姿势:解题报告

那么,以群赛里的这个题为模版吧:

Problem: 喵喵的遗憾

Code: acdream1124.cpp


然后觉得有必要改一下之前做过的一个题的姿势

Problem: A Short problem

之前的做法是暴力递推式,找循环节,由于取模数已经固定了,暴出来后就不需要重新计算,所以时限很好搞定,万一取模数是输入的呢,原来的办法就跪了吧

开始的时候有点sb,直接只改了矩阵的部分,发现循环节求出来loop(1000000007)=222222224,loop(222222224)=36624!=183120,难道是模版有问题?但是我看了思路没问题啊,郁闷了好久

今天早上起来后,看了下代码,为什么要判断5是不是p的模二次剩余呢,为什么是5呢

想了想,5对于斐波那契数列来讲,不就是x^2=x+1的delta么,那么这题的递推式是x^2=3*x+1,delta=3*3+4=13,然后我就把勒让德符号判断二次剩余那里改成13,然后对应的暴力出13及13以内的素数对应的循环节,交了一发,AC了

Code:hdu4291.cpp


然后顺便把这道题也过了吧

Problem: Evil teacher's Final Problem

同样是斐波那契数列的循环节,只不过递归的层数可能有1w,没有什么技巧,多加了个map存求过的答案

Code: hdu3978.cpp


当然从一开始,我们要解决的是斐波那契循环节的问题,但是我们发散思维想一想,是不是可以求一系列矩阵快速幂中的类似问题,像那个g(n)=3*g(n-1)+g(n-2)的问题,诸如此类的递推式的循环节都可以这样求了吧


大致说下递推式循环节的解决方案:

problem: f(n)=a*f(n-1)+b*f(n-2),求f(n)%p的循环节

solution: 

1.对p进行质因数分解,p = p1^a1 * p2^a2 * p3^a3 ... * pn^an

2.分别求 p1^a1,p2^a2,...,pn^an的循环节,然后取最小公倍数

至于怎么求对 px^ax 的循环节,这里用到了二次剩余

2.1 p mod px^ax 的循环节 = G(px) * px^(ax-1) , G(px) 就是 p mod px 的最小循环节

2.2 对于递推式,我们可以得到特征根方程 x^2=a*x+b ,delta=a*a+4*b

2.3 对于G(px),如果delta是模px的二次剩余,G(px)是px-1的因子,否则G(px)是(px-1)*(px+1)的因子

暴力找到最小的就可以了

Problem: 神奇的%系列三

Code: acdream1075.cpp



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值