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 m. 0� n� 2147483647 and 0� m< 20. Note that a mod b gives the remainder when a is divided by b.
Input consists of several lines specifying a pair of n and m. Output should be corresponding Mn, one per line.
11 7 11 6
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; }