10299 Problem A: Modular Fibonacci(斐波那契的矩阵快速幂)

Problem A: Modular Fibonacci

The Fibonacci numbers (0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...) are defined by the recurrence:

F0 = 0
F1 = 1
Fi = Fi-1 + Fi-2 
for i>1

Write a program which calculates Mn = Fn mod 2m for given pair of n and m0 n 2147483647 and 0 m20. Note that a mod b gives the remainder when a is divided by b.

Input and Output

Input consists of several lines specifying a pair of n and m. Output should be corresponding Mn, one per line.

Sample Input

11 7
11 6

Sample Output

89
25
题意:给定n和m,求斐波那契数列第Fn %(2 ^ m)

思路:斐波那契数列的矩阵快速幂  [1 1] * [Fn + 1]  =  [Fn + 1 + Fn = Fn + 2] 这样只要求出[1 1] 这个矩阵的n次方乘上[F2] 就可以得到第Fn项。然后就是矩阵的

                                                              [1 0]    [Fn]             [Fn + 1]                                                  [1 0]                                       [F1]                                                                  快速幂取模。注意要用longlong

代码:

#include <stdio.h>
#include <string.h>

long long n, mm;

struct ju {
	long long m[2][2];
	ju() {
		memset(m, 0, sizeof(m));	
	}
} m1, m2, m3, m4;

ju mul(ju a, ju b) {
	ju c;
	for (int i = 0; i < 2; i ++) {
		for (int j = 0; j < 2; j ++) {
			for (int k = 0; k < 2; k ++) {
				c.m[i][j] = (c.m[i][j] + a.m[i][k] * b.m[k][j]) % mm;		
			}
		}
	}
	return c;
}

void mi(long long k) {
	m4.m[0][0] = m4.m[1][1] = m1.m[0][0] = m1.m[0][1] = m1.m[1][0] = 1; 
	m4.m[0][1] = m4.m[1][0] = m1.m[1][1] = 0;
	while (k != 1) {
		m2 = m1;
		m3 = mul(m1, m1);
		m1 = m3;
		if (k & 1) {
			m3 = mul(m4, m2);
			m4 = m3;
		}
		k = k>>1;
	}
	m3 = mul(m1, m4);
	m1 = m3;
}
int main() {
	while (~scanf("%lld%lld", &n, &mm)) {
		if (n == 0 || mm == 0) {
			printf("0\n"); continue;
		}
		mm = 1<<mm;
		mi(n);
		printf("%lld\n", m1.m[0][1]); 
	}
	return 0;
}



你可能感兴趣的:(10299 Problem A: Modular Fibonacci(斐波那契的矩阵快速幂))