题意:给出n和m,求出f(n) % m, f(x)为斐波那契数列。
思路:因为n挺大的,如果直接利用公式计算很有可能会TLE,所以利用矩阵快速幂求解,|(1, 1), (1, 0)| * |f(n - 1), f(n - 2)| = |f(n), f(n - 1)|,所以求f(n)相当于|f(1), f(0)|乘上n - 1次的|(1, 1), (1, 0)|。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
typedef long long ll;
using namespace std;
ll n, p, k;
int m;
struct mat{
ll s[2][2];
mat(ll a = 0, ll b = 0, ll c = 0, ll d = 0) {
s[0][0] = a;
s[0][1] = b;
s[1][0] = c;
s[1][1] = d;
}
}c(1, 1, 1, 0), tmp(1, 0, 0, 1);
mat operator * (const mat& a, const mat& b) {
mat Mat;
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
Mat.s[i][j] = (a.s[i][0] * b.s[0][j] + a.s[i][1] * b.s[1][j]) % p;
return Mat;
}
mat pow_mod(ll k) {
if (k == 0)
return tmp;
else if (k == 1)
return c;
mat a = pow_mod(k / 2);
a = a * a;
if (k % 2)
a = a * c;
return a;
}
int main() {
while (scanf("%lld%d", &n, &m) != EOF) {
p = pow(2, m);
if (n) {
mat ans = pow_mod(n - 1);
k = ans.s[0][0];
}
else
k = 0;
printf("%lld\n", k);
}
return 0;
}