北邮12月份月赛 D 矩阵二分幂

     是一道数学题吧,用矩阵二分幂可以轻松解决。以前在NYOJ上做过类似的题,所以比赛时直接贴的以前的代码,,水过。。。。。数据太水啊。。。。。题目:

D  零零漆的跳槽
Accept:42     Submit:117
Time Limit:1000MS     Memory Limit:65536KB

Description

世上没有铁饭碗, 也没有永远的老板跳槽风也刮到了组织尽管组织极力想挽留零零漆但他还是依然要跳到另一个有关部门凭他的经验以及高超的杀猪功力他顺利的通过了有关部门前面的测试来到了算法测试关给他的问题很简单----给两个整数n,m, 求斐波纳契数fib[n] % m...

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

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

/ fib[0]=0

| fib[1]=1

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

Input

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

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

Output

对于每对n,m, 对应输出单独的一行包含一个整数 r = fib[n] % 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

ac代码:

#include <stdio.h>
//int f(int x,int y,int a,int b)
//{
//	return a*x+b*y;
//}
int main()
{
	int n,m,i,j,k,t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);

		int a[2][2]={1,0,1,0},b[2][2]={1,1,1,0},t[2][2]; 
		while(n)
		{
			if(n&1)
			{
				t[0][0]=(a[0][0]*b[0][0]+a[0][1]*b[1][0])%m;
				t[0][1]=(a[0][0]*b[0][1]+a[0][1]*b[1][1])%m;
				t[1][0]=(a[1][0]*b[0][0]+a[1][1]*b[1][0])%m;
				t[1][1]=(a[1][0]*b[0][1]+a[1][1]*b[1][1])%m;
				a[0][0]=t[0][0];a[0][1]=t[0][1];a[1][0]=t[1][0];a[1][1]=t[1][1];
			}
			t[0][0]=(b[0][0]*b[0][0]+b[0][1]*b[1][0])%m;
			t[0][1]=(b[0][0]*b[0][1]+b[0][1]*b[1][1])%m;
			t[1][0]=(b[1][0]*b[0][0]+b[1][1]*b[1][0])%m;
			t[1][1]=(b[1][0]*b[0][1]+b[1][1]*b[1][1])%m;
			b[0][0]=t[0][0];b[0][1]=t[0][1];b[1][0]=t[1][0];b[1][1]=t[1][1];
			n=n>>1;
		}
		printf("%d\n",a[0][1]);

	}
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值