Jzzhu and Sequences(CF-450B)
Problem 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).
Examples
Input
2 3
3Output
1
Input
0 -1
2Output
1000000006
题意:输入 x,y,n,其中 f(1)=x,f(2)=y,f(i)=f(i-1)+f(i+1),求 f(n)
思路: n 很大,直接递推的话一定会 TLE
可以考虑构造满足递推式的矩阵用矩阵快速幂来求
已知:,那么有:
即:,则:
构造系数矩阵,有:
化简得:
所以答案即为系数矩阵的 n-2 次幂的值 A[1][1]*y+A[1][2]*x
此外要注意特判
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define PI acos(-1.0)
#define E 1e-9
#define INF 0x3f3f3f3f
#define LL long long
const int MOD=1e9+7;
const int N=10+5;
const int dx[]= {-1,1,0,0};
const int dy[]= {0,0,-1,1};
using namespace std;
struct Matrix{
LL s[N][N];
};
Matrix e;//单位矩阵E
Matrix x;//构造矩阵
void init(){
for(int i=1;i<=2;i++)//主对角线为1
e.s[i][i]=1;
//构造矩阵
x.s[1][1]=1;x.s[1][2]=-1;
x.s[2][1]=1;x.s[2][2]=0;
}
Matrix mul(Matrix A,Matrix B,LL n){//矩阵乘法,n代表A、B两个矩阵是n阶方阵
Matrix temp;//临时矩阵,存放A*B结果
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
temp.s[i][j]=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
temp.s[i][j]=(temp.s[i][j]+A.s[i][k]*B.s[k][j])%MOD;
return temp;
}
Matrix quickPower(Matrix a,LL b,LL n){//矩阵快速幂,求矩阵n阶矩阵的b次幂
Matrix ans=e;
while(b){
if(b&1)
ans=mul(ans,a,n);//ans=e*a
a=mul(a,a,n);//a=a*a
b>>=1;
}
return ans;
}
int main(){
init();
LL x0,y0,n;
while(scanf("%lld%lld%lld",&x0,&y0,&n)!=EOF){
if(x0==0&&y0==0)
printf("0\n");
else if(n==1)
printf("%lld\n",(x0%MOD+MOD)%MOD);
else if(n==2)
printf("%lld\n",(y0%MOD+MOD)%MOD);
else{
Matrix res=quickPower(x,n-2,2);
LL temp=(res.s[1][1]*y0+res.s[1][2]*x0)%MOD;
if(temp<0)
temp=(temp%MOD+MOD)%MOD;
printf("%lld\n",temp);
}
}
return 0;
}