CodeForces 450B Jzzhu and Sequences(矩阵快速幂)题解
思路:
之前那篇完全没想清楚,给删了,下午一上班突然想明白了。
讲一下这道题的大概思路,应该就明白矩阵快速幂是怎么回事了。
我们首先可以推导出
学过矩阵的都应该看得懂,我们把它简写成T*A(n-1)=A(n),是不是有点像等比?然后我们得到T^(n-1)*A(1)=A(n),所以我们可以通过矩阵快速幂快速计算左边的T^n-1这个式子,最后再和A1相乘,那么第一个数字就是答案了。
代码:
#include<set>
#include<cstring>
#include<cstdio>
#include<algorithm>
const int maxn = 2;
const int MOD = 1000000000+7;
const int INF = 0x3f3f3f3f;
using namespace std;
struct Mat{
int s[maxn][maxn];
void init(){
for(int i = 0;i < maxn;i++)
for(int j = 0;j < maxn;j++)
s[i][j] = 0;
}
};
Mat mul(Mat a,Mat b){
Mat t;
t.init();
for(int i = 0;i < maxn;i++){
for(int j = 0;j < maxn;j++){
for(int k = 0;k < maxn;k++){
t.s[i][j] = (t.s[i][j] + a.s[i][k]*b.s[k][j])%MOD;
}
}
}
return t;
}
Mat pow_mat(Mat p,int n){
Mat ret;
ret.init();
ret.s[0][0] = ret.s[1][1] = 1;
while(n){
if(n & 1) ret = mul(ret,p);
p = mul(p,p);
n >>= 1;
}
return ret;
}
int main(){
int x,y,n;
Mat a;
a.s[0][0] = 1;
a.s[0][1] = -1;
a.s[1][0] = 1;
a.s[1][1] = 0;
scanf("%d%d%d",&x,&y,&n);
if(n == 1){
printf("%d\n",(x%MOD + MOD)%MOD);
}
else if(n == 2){
printf("%d\n",(y%MOD + MOD)%MOD);
}
else{
a = pow_mat(a,n - 2);
printf("%d\n",((y*a.s[0][0] + x*a.s[0][1])%MOD +MOD)%MOD);
}
return 0;
}