资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
斐波那契数列大家都非常熟悉。它的定义是:
f(x) = 1 .... (x=1,2)
f(x) = f(x-1) + f(x-2) .... (x>2)
对于给定的整数 n 和 m,我们希望求出:
f(1) + f(2) + ... + f(n) 的值。但这个值可能非常大,所以我们把它对 f(m) 取模。
公式参见【图1】
但这个数字依然很大,所以需要再对 p 求模。
数据格式
输入为一行用空格分开的整数 n m p (0 < n, m, p < 10^18)
输出为1个整数
例如,如果输入:
2 3 5
程序应该输出:
0
再例如,输入:
15 11 29
程序应该输出:
25
资源约定:
峰值内存消耗 < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。
提交时,注意选择所期望的编译器类型。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, m, p;
struct Matrix {
ll m[3][3];
Matrix() {m[1][1] = m[1][2] = m[2][1] = m[2][2] = 0;}
Matrix(ll a, ll b, ll c, ll d) {
m[1][1] = a;
m[1][2] = b;
m[2][1] = c;
m[2][2] = d;
}
};
ll mul(ll a, ll b, ll mod) {
ll res = 0;
while(b) {
if(b&1) res = (res + a) % mod;
(a<<=1) %= mod;
b>>=1;
}
return res;
}
Matrix Matrix_mul(Matrix a, Matrix b, ll mod) {
Matrix res;
for(int i = 1;i <= 2;i ++)
for(int j = 1;j <= 2;j ++)
for(int k = 1;k <= 2;k ++)
res.m[i][j] = (res.m[i][j] + mul(a.m[i][k], b.m[k][j], mod)) % mod;
return res;
}
ll Fib(ll n, ll mod) {
Matrix res = Matrix(1, 0, 1, 0);
Matrix a = Matrix(1, 1, 1, 0);
while(n) {
if(n&1) res = Matrix_mul(res, a, mod);
a = Matrix_mul(a, a, mod);
n>>=1;
}
return res.m[1][2];
}
int main()
{
cin>>n>>m>>p;
if(m > n+2) printf("%lld\n", (Fib(n+2, p) + p - 1) % p); // 如果m>n+2,则S(n) = f(n+2)-1 < f(n+2) < f(m),那无需对f(m)进行取模操作
else {
ll Fm = Fib(m, LONG_LONG_MAX); // 得到f(m),因为没法实现边进行矩阵快速幂边取模的操作,因此评测的数据必然能保证将f(m)求出来
printf("%lld\n", (Fib(n+2, Fm) + p - 1) % p);
}
return 0;
}