您的位置:首页 > 产品设计 > UI/UE

Jzzhu and Sequences CodeForces - 450B (矩阵快速幂)

2017-08-12 14:03 471 查看
题目链接:点我

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




You are given x and y, please calculate fn modulo 1000000007 (1e9 + 7).


Input

The first line contains two integers x and y (|x|, |y| ≤ 1e9). The second line contains a single integer n (1 ≤ n ≤ 2·1e9).


Output

Output a single integer representing fn modulo 1000000007 (1e9 + 7).


Example

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 (1e9 + 7) equals (1e9 + 6).


题意:

计算递推式的第n项对1e9 + 7 取模.

思路:

矩阵快速幂, 由于题目所给的 n 很大,我们不能直接递推出来,那么我们可以用矩阵快速幂来加速这个递推过程,矩阵快速幂的原理其实和快速幂的原理是一样的,只是变成了矩阵乘法.对于递推式


具体矩阵请看代码.

代码:

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

typedef long long LL;
const int mod = 1e9 + 7;

struct mat{
LL a[3][3];
mat(){memset(a, 0 ,sizeof(a));}
mat operator *( mat b){//重载矩阵乘法
mat c;
for(int  i = 1; i <= 2; ++i)
for(int k = 1; k <= 2; ++k){
if(a[i][k])//一个小小的优化,但有时候很有用.
for(int  j = 1; j <= 2; ++j){
c.a[i][j] += a[i][k] * b.a[k][j] ;
c.a[i][j] =  (c.a[i][j] % mod + mod ) %mod;
}
}return c;
}
};

mat qpow(mat x, LL n){
mat ans;
ans.a[1][1] = ans.a[2][2] = 1;//单位矩阵,
while(n){
if(n & 1) ans = ans * x;
x = x * x;
n >>= 1;
}
return ans;
}

int main(){
LL x, y, n;
scanf("%I64d %I64d %I64d", &x, &y, &n);
x = (x % mod + mod) % mod;
y = (y % mod + mod) % mod;
if(n == 1){
printf("%I64d\n",(x + mod ) % mod);
return 0;
} if(n == 2){
printf("%I64d\n",(y + mod) % mod);
return 0;
} mat q;
q.a[1][1]= q.a[2][1] = 1;//递推矩阵
q.a[1][2] = -1;
mat ans ;
ans = qpow(q, n-2);
LL sum = ans.a[1][1] * y % mod + ans.a[1][2] * x % mod;
printf("%I64d\n", (sum% mod + mod) % mod);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: