# CodeForces 450B Jzzhu and Sequences （矩阵优化）

### Description

Jzzhu has invented a kind of sequences, they meet the following property:

$f_1=x$

$f_2=y$

$f_i=f_{i-1}+f_{i+1}\text {(i>2)}$

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

Input1:
2 3
3
Input2:
0 -1
2

Output1:
1
Output2:
1000000006

### Http

CodeForces:https://vjudge.net/problem/CodeForces-450B

## 解决思路

$f_{i+1}=f_i-f_{i-1}$

$f_i=f_{i-1}-f_{i-2}$

$T=\begin{bmatrix} 1 & 1 \\ -1 & 0 \end{bmatrix}$

## 代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;

#define ll long long//为了防止越界，统一全部用long long存
const ll Mod=1000000007;

class Matrix//定义一个矩阵结构体
{
public:
ll A[2][2];
Matrix()//初始化。为了方便下面的运算，这里定义两种初始化，一种是直接全部为０，另一种是用一个二维数组给定其初值
{
memset(A,0,sizeof(A));
}
Matrix(ll arr[2][2])
{
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
A[i][j]=arr[i][j];
}
};

Matrix operator * (Matrix A,Matrix B)//重载乘法运算
{
Matrix Ans;
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
for (int k=0;k<2;k++)
Ans.A[i][j]=(Ans.A[i][j]+(A.A[i][k]*B.A[k][j]+Mod)%Mod+Mod)%Mod;//注意这里的取膜操作，防止了负数越界
return Ans;
}

int main()
{
ll x,y,n;
cin>>x>>y>>n;
x=(x+Mod)%Mod;//这里因为x和y再输入的时候就有可能是负数（比如样例２），所以先取一次膜
y=(y+Mod)%Mod;
if (n==1)//ｎ为１和２的时候直接输出
{
cout<<x<<endl;
return 0;
}
if (n==2)
{
cout<<y<<endl;
return 0;
}
ll a[2][2]={{y,x},{0,0}};
ll b[2][2]={{1,1},{-1,0}};
Matrix A(a);
Matrix B(b);
n=n-2;//这里要-2是因为1和2的已经处理了，现在只要乘以n-2次
while (n!=0)//矩阵快速幂
{
if (n&1)
A=A*B;
B=B*B;
n=n>>1;
}
cout<<A.A[0][0]<<endl;
return 0;
}

posted @ 2017-07-20 17:17  SYCstudio  阅读(264)  评论(0编辑  收藏