A - Jzzhu and Sequences
Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u
Submit
 
Status
 
Practice
 
CodeForces 450B
Appoint description: 
Description

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).

Sample Input

Input
2 3
3
Output
1
Input
0 -1
2
Output
1000000006
Hint

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).
 

题意:

 f1 = x, f2 = y; fi = f(i-1) + f(i+1),求f[n]
       

分析:

因为

fi = f(i-1) + f(i+1)

所以

f(i+1)=f(i)-f(i-1)

fi = f(i-1)-f(i-2)

所以,

f(i)=1*f(i-1)-1*f(i-2)

f(i-1)=1*f(i-1)

构造矩阵A

1 -1

1 0

f(n)                        f(2)

f(n-1)= A^(k-2)*f(1)

注意取mod

 

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<iomanip>
#include<cmath>
#include<cstring>
#include<vector>
#define N 10005
using namespace std;
const int MAXN= 100;
const int p=1000000007;
typedef long long ll;
ll len;
struct Matrix
{
long long M[MAXN][MAXN];
Matrix(const bool I = 0) ///初始化对角矩阵
{
memset(M, 0, sizeof(M));
if (I)
for(int i = 0; i < len; i++)
M[i][i] = 1;
}
Matrix operator *(const Matrix &y) ///矩阵乘法,对乘法重新定义
{
Matrix z;
for (int i = 0; i < len; i++)
for (int j = 0; j < len; j++)
for (int k = 0; k < len; k++)
z.M[i][j] = (z.M[i][j]+M[i][k]*y.M[k][j]%p)%p;
return z;
}
void out()
{
for (int i = 0; i <len; i++)
{
for (int j = 0; j < len; j++)
cout << M[i][j] << " ";
cout << "\n";
}
}
};
Matrix pow(Matrix A, long long b)///矩阵的快速幂
{
Matrix ans = Matrix(1);
for (; b; b>>=1)
{
if (b&1) ans = ans*A;
A = A*A;
}
return ans;
}
int main()
{
int T;
len=2; ///构造矩阵的长度
ll x,y,k;
while(scanf("%lld%lld%lld",&x,&y,&k)!=-1)
{
if(k==2) printf("%lld\n",(p+y%p)%p);
else if(k==1) printf("%lld\n",(x%p+p)%p) ;
else
{
Matrix ans;

ans.M[0][0] = 1;
ans.M[0][1] = -1;
ans.M[1][0] = 1;
ans.M[1][1] = 0;

ans = pow(ans,k-2);
//ans.out();
ll ans1=(ans.M[0][0]*y%p+ans.M[0][1]*x%p+p)%p;
while(ans1<0) ans1+=p;
printf("%lld\n",ans1);

}

}




return 0;
}