矩阵快速幂
题目
Jzzhu has invented a kind of sequences, they meet the following property:
You are given x and y, please calculate f n modulo 1000000007 (109 + 7).
输入
The first line contains two integers x and y (|x|, |y| ≤ 109). The second line contains a single integer n (1 ≤ n ≤ 2·109).
输出
Output a single integer representing f n modulo 1000000007 (109 + 7).
示例
- 输入
2 3
3 - 输出
1 - 输入
0 -1
2 - 输出
1000000006
Note
In the first sample, f 2 = f 1 + f 3, 3 = 2 + f 3, f 3 = 1.
In the second sample, f 2 = - 1; - 1 modulo (109 + 7) equals (109 + 6).
解题
方法一:找规律
#include <iostream>
using namespace std;
const int MOD = 1000000007;
const int N = 6;
int ans[N];
int main()
{
int x, y, n;
cin >> x >> y >> n;
// Init ans
ans[0] = x - y;
ans[1] = x;
ans[2] = y;
ans[3] = y - x;
ans[4] = -x;
ans[5] = -y;
int result = ans[n % N];
if (result >= 0)
cout << result % MOD << endl;
else
cout << (result % MOD + MOD) % MOD << endl;
return 0;
}
方法二:矩阵快速幂
#include <iostream>
#include <memory.h>
using namespace std;
const int MOD = 1000000007;
const int N = 2;
class Matrix
{
public:
int n;
long long int m[N][N];
Matrix()
{
memset(m, 0, sizeof(m));
}
Matrix operator*(const Matrix &y)
{
Matrix z;
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < N; k++)
{
z.m[i][j] += m[i][k]%MOD * y.m[k][j]%MOD;
z.m[i][j] %= MOD;
}
return z;
}
};
Matrix Matrix_Powmul(int x, int y, Matrix t, int n)
{
Matrix z;
z.m[0][0] = y;
z.m[0][1] = x;
z.m[1][0] = 0;
z.m[1][1] = 0;
while (n)
{
if (n & 1)
{
z = z * t;
}
n >>= 1;
t = t*t;
}
return z;
}
int main()
{
int x, y, n;
int result;
cin >> x >> y >> n;
if (n==1)
result = x;
else if (n==2)
result = y;
else
{
Matrix t;
t.m[0][0] = 1;
t.m[0][1] = 1;
t.m[1][0] = -1;
t.m[1][1] = 0;
Matrix f = Matrix_Powmul(x, y, t, n-2);
result = f.m[0][0]%MOD;
}
if (result>=0)
result%=MOD;
else
{
result = result + MOD; // 语句:result = f.m[0][0]%MOD; 已经取模。
}
cout<<result<<endl;
}