Jzzhu and Sequences CodeForces - 450B
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).
题意:
给定递推式
分析:
我们可以转化递推式
即:
因此可以得到关系矩阵
对于
注意步步取模
code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
const ll mod = 1e9+7;
ll x,y,n;
struct Matrix{
ll mat[3][3];
Matrix operator * (const Matrix &b)const{
Matrix ans;
for(int i = 0; i < 2; i++){
for(int j = 0; j < 2; j++){
ans.mat[i][j] = 0;
for(int k = 0; k < 2; k++){
ans.mat[i][j] = (ans.mat[i][j] + mat[i][k] * b.mat[k][j] % mod + mod) % mod;
}
}
}
return ans;
}
};
Matrix q_pow(Matrix a,ll b){
Matrix ans;
memset(ans.mat,0,sizeof(ans.mat));
for(int i = 0; i < 2; i++){
ans.mat[i][i] = 1;
}
while(b){
if(b & 1)
ans = ans * a;
b >>= 1;
a = a * a;
}
return ans;
}
int main(){
scanf("%lld%lld",&x,&y);
scanf("%lld",&n);
if(n == 1){
printf("%lld\n",(x % mod + mod) % mod);
return 0;
}
if(n == 2){
printf("%lld\n",(y % mod + mod) % mod);
return 0;
}
Matrix ans;
ans.mat[0][0] = 1;
ans.mat[0][1] = -1;
ans.mat[1][0] = 1;
ans.mat[1][1] = 0;
ans = q_pow(ans,n-2);
ll ret = ((ans.mat[0][0] * y % mod + ans.mat[0][1] * x % mod) % mod + mod) % mod;
printf("%lld\n",ret);
return 0;
}