B. Jzzhu and Sequences
time limit per test 1 second
memory limit per test 256 megabytes
input standard input
output standard output
Jzzhu has invented a kind of sequences, they meet the following property:
You are given x and y, please calculate fn modulo 1000000007 (109 + 7).
Input
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
Output a single integer representing fn modulo 1000000007 (109 + 7).
Examples
Input
2 3
3
Output
1
Input
0 -1
2
Output
1000000006
Note
In the first sample, f2 = f1 + f3, 3 = 2 + f3, f3 = 1.
In the second sample, f2 = - 1; - 1 modulo (109 + 7) equals (109 + 6).
解题思路:
给定
f(1)和f(2)
f
(
1
)
和
f
(
2
)
,求
f(n)
f
(
n
)
分析:
特判
f(1),f(2)
f
(
1
)
,
f
(
2
)
当
n>=3
n
>=
3
时使用矩阵快速幂即可
将公式转化一下 , 可以得到一个变换矩阵
由
F(i)=F(i−1)+F(i+1)
F
(
i
)
=
F
(
i
−
1
)
+
F
(
i
+
1
)
;
将左式移到右边得
F(i+i)=F(i)-F(i-1);
下标同时减一得
F(i)=F(i-1)-F(i-2);
从而构造矩阵
(F(i-1),F(i-2))[1 , -1 ]=(F(i),F(i-1))[1 , 0 ]
带入i=3,得
(F(2)=y,F(1)=x)∗[1,−1](i−2)=(F(3),F(2)) ( F ( 2 ) = y , F ( 1 ) = x ) ∗ [ 1 , − 1 ] ( i − 2 ) = ( F ( 3 ) , F ( 2 ) ) *[1 , 0 ]
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#define ll long long
using namespace std;
const int MAXN = 1e5 + 7;
ll mod = 1e9+7;
struct Matrix{
ll m[2][2];
} ans, base;
struct Matrix mult(struct Matrix a, struct Matrix b) {
struct Matrix c;
for(int i = 0; i < 2; i++)
for(int j = 0; j < 2; j++)
{
c.m[i][j]=0;
for(int k = 0; k < 2; k++)
c.m[i][j] += (a.m[i][k]*b.m[k][j])%mod;
c.m[i][j] %= mod;
}
return c;
}
void powl(ll n)
{
base.m[0][0] =1;
base.m[0][1] = -1;
base.m[1][0] = 1;
base.m[1][1] = 0;
ans.m[0][0] = ans.m[1][1] = 1; // ans 初始化为单位矩阵
ans.m[0][1] = ans.m[1][0] = 0;
while(n)
{
if(n&1) ans = mult(ans,base);
base = mult(base,base);
n >>= 1;
}
}
int main()
{
ll x,y,n;
scanf("%lld%lld%lld",&x,&y,&n);
if(n == 1) printf("%lld\n",(x%mod + mod)%mod);
else if(n == 2) printf("%lld\n",(y%mod + mod)%mod);
else {
powl(n-2);
ll result = (((ans.m[0][0]*y+ans.m[0][1]*x)%mod)+mod)%mod;
printf("%lld\n",result);
}
return 0;
}