您的位置:首页 > 其它

xmu 1018 零零漆的作

2015-08-30 11:56 218 查看
Description

   世上没有铁饭碗, 裁员风也刮到了组织, 尽管零零漆为组织做了那么多贡献, 他还是得通过组织的素质能力以及水平测试才能继续他的特工工作. 凭他的经验以及高超的杀猪功力, 他顺利的通过了前面的测试, 来到了算法测试关. 给他的问题很简单----给两个整数n,m, 求斐波纳契数fib
% m...

算卖肉钱久了, 零零漆还真想不起怎么去计算斐波纳契数了, 但是他在考场竟然能通过安装在皮鞋里的电话和你通信, 他只能寄希望于你了...

当然你还是知道fib
的定义的:

/ fib[0]=0

| fib[1]=1

\ fib
=fib[n-1]+fib[n-2] (n>1)

Input

   输入第一行是一个整数 c, 0 < c <= 5000, 表示要计算多少个fib

接下来的c行, 每行有两个整数n,m, 0 <= n <= 2147483647, 0 < m < 32767, 意义如前所述

Output

   对于每对n,m, 对应输出单独的一行, 包含一个整数 r = fib
% m

Sample Input

8

42 8468

6335 6501

19170 5725

11479 9359

26963 4465

5706 8146

23282 6828

9962 492

Sample Output

3712

3547

1210

5683

1502

5894

5113

1

Source

xmu @ arxor @ alrale

首先这个题目是一类典型问题中的一个。就是用矩阵乘法解决加速状态转移。

现在我们需要构造一个2 x 2的矩阵,使得它乘以(fib[n-2],fib[n-1])得到的结果是(fib[n-1],fib[n-1]+fib[n-2])。每多乘一次这个矩阵,这两个数就会多迭代一次。那么,我们把这个2 x 2的矩阵自乘n次,再乘以(0,1)就可以得到第n个Fib数了不用多想,这个2 x 2的矩阵很容易构造出来:



具体分解一下就是如下步骤:



是不是瞬间明白什么了看完上面的分解步骤是不是豁然开朗了呢?

类似的问题matrix67有一篇非常不错的文章 看文戳这里

一段N年前的代码

#include<stdio.h>
int A,B,C,D,m;
void cal (int&a,int &b,int &c,int&d,int n)
{
if (n>1)
{
if(n%2)
{
cal(a,b,c,d,n-1);
A = (a+c)%m;
B = (b+d)%m;
C = a;
D = b;
}
else
{
cal(a,b,c,d,n/2);
A = (a*a+b*c)%m;
B = (a*b+b*d)%m;
C = (c*a+d*c)%m;
D = (c*b+d*d)%m;
}
a = A;
b = B;
c = C;
d = D;
}
}
int main ()
{

int a,b,c,d,n,T;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&n,&m);
n--;
a =b =c =1;
d =0;
if(n)
{
cal(a,b,c,d,n);
printf("%d\n",a%m);
}
else
printf("0\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: