题目链接:https://vjudge.net/problem/HDU-4549

M斐波那契数列

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 4492    Accepted Submission(s): 1397

Problem Description
M斐波那契数列F[n]是一种整数数列,它的定义如下:

F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )

现在给出a, b, n,你能求出F[n]的值吗?

 
Input
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
 
Output
对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
 
Sample Input
0 1 0
6 10 2
 
Sample Output
0
60
 
Source
 
Recommend
liuyiding

题解:

1.可知f[n]中a、b的指数符合斐波那契数列,因而可用矩阵快速幂求出。

2.然而如果指数不求模,也可能会溢出。但指数又怎样求模呢?

有如下定理:当m为素数,且a、n互质时, a^n % m = a^(n%(m-1)) % m

证明:

根据费马小定理,当m为素数,且a、p互质时, a^(m-1) ≡ 1 (mod m),

a^n = a^(k*(m-1)+r) = (a^(m-1))^k * a^r,其中 r = n%(m-1),

那么 a^n % m = ( (a^(m-1))^k * a^r ) % m =  (a^(m-1))^k % m * a^r % m = 1 * a^r % m = a^(n%(m-1)) % m 。

所以:当m为素数,且a、n互质时, a^n % m = a^(n%(m-1)) % m

代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = ;
const int MAXN = 1e6+; const int Size = ;
struct MA
{
LL mat[Size][Size];
void init()
{
for(int i = ; i<Size; i++)
for(int j = ; j<Size; j++)
mat[i][j] = (i==j);
}
}; MA mul(MA x, MA y)
{
MA ret;
memset(ret.mat, , sizeof(ret.mat));
for(int i = ; i<Size; i++)
for(int j = ; j<Size; j++)
for(int k = ; k<Size; k++)
ret.mat[i][j] += (1LL*x.mat[i][k]*y.mat[k][j])%(MOD-), ret.mat[i][j] %= (MOD-);
return ret;
} MA qpow(MA x, LL y)
{
MA s;
s.init();
while(y)
{
if(y&) s = mul(s, x);
x = mul(x, x);
y >>= ;
}
return s;
} LL q_pow(LL x, LL y)
{
LL s = ;
while(y)
{
if(y&) s *= x, s %= MOD;
x *= x, x %= MOD;
y >>= ;
}
return s;
} MA tmp = {
, ,
,
}; int main()
{
LL f[], n;
while(scanf("%lld%lld%lld",&f[],&f[],&n)!=EOF)
{
if(n<=)
{
printf("%lld\n", f[n]%MOD);
continue;
} MA s = tmp;
s = qpow(s, n-);
LL p1 = s.mat[][];
LL p2 = s.mat[][];
LL ans = q_pow(f[], p2)*q_pow(f[], p1)%MOD;
printf("%lld\n", ans);
}
}

最新文章

  1. 百度地图、ECharts整合HT for Web网络拓扑图应用
  2. 002:IPC与system函数简介
  3. 大话胖model和瘦model
  4. 使用jquery合并表格中相同文本的相邻单元格
  5. 云计算之KVM简介(一)
  6. 资源 | 数十种TensorFlow实现案例汇集:代码+笔记
  7. AS3 Graphics 多次绘制
  8. 键盘游戏之canvas--用OO方式写
  9. vbs和qtp一些脚本
  10. ASP.NET异常处理机制
  11. 如何清除PHP中不需要的Layout模板
  12. 【Java编程】Eclipse快捷键
  13. Windows下安装ZooKeeper
  14. tkinter学习系列之(六)Radiobutton控件
  15. Azkaban集群部署
  16. 【Python】【亲测好用】安装第三方包报错:AttributeError:&#39;module&#39; object has no attribute &#39;main&#39;
  17. 百度BAE 平台PHP对Mongodb的连接
  18. json格式的javascript对象用法分析
  19. 雷林鹏分享:Ruby 正则表达式
  20. 《C++ Primer Plus》读书笔记之三—循环与关系表达式

热门文章

  1. Codeforces 323 B Tournament-graph
  2. JD静态网页
  3. Nginx图片防盗链的方式
  4. HDU 5289 Assignment(单调队列)
  5. [Algorithm] Write a Depth First Search Algorithm for Graphs in JavaScript
  6. java实验8-Java输入输出流
  7. Spring &lt;context:annotation-config&gt; 和 &lt;context:component-scan&gt;区别
  8. mysql 清空或删除表数据后,控制表自增列值的方法
  9. 【转载】C#扫盲之:带你掌握C#的扩展方法、以及探讨扩展方法的本质、注意事项
  10. Allegro16.6和17.0和17.2中将板框导出DXF文件