So Easy!
题面
题意
给一个n然后利用公式求出S(n)的值
分析
这是一道矩阵快速幂的模板题目
我们设 (a+√b)n=x+y√b其中(a−1)2<b<a2,那么ceil(√b)=a;我们可以知道 (a+√b)n=xn+yn√b=(a+√b)n−1∗(a+√b)=(xn.−.1+yn.−.1√b)∗(a+√b)=(xn.−.1∗a+yn.−.1b)+(a∗yn.−.1+xn.−.1)∗√b,这时,我们就可以得到一个递归式,而且这个递归式可以用矩阵行列式表示,
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
ll a,m,b,n;
struct martix{
ll mo[3][3];
martix(){
memset(mo,0,sizeof(mo));
}
};///定义一种新的结构类型(矩阵)
martix mul(martix a,martix b){
martix c;
for(ll i=1;i<=2;i++){
for(ll j=1;j<=2;j++){
for(ll k=1;k<=2;k++){
c.mo[i][j]=(c.mo[i][j]+a.mo[i][k]*b.mo[k][j])%m;
}
}
}
return c;
}///计算二阶与二阶的行列式相乘
martix powmo(martix al,ll n){
martix T;
T.mo[1][1]=1;
T.mo[2][2]=1;///初始化为单位矩阵
while(n){
if(n&1){
T=mul(al,T);
}
n>>=1;
al=mul(al,al);
}
return T;
}///计算行列式al的n次方
int main(){
while(cin>>a>>b>>n>>m) {
martix q;
q.mo[1][1]=a;q.mo[1][2]=b;
q.mo[2][1]=1;q.mo[2][2]=a;
martix res=powmo(q,n);
cout<<(2*res.mo[1][1])%m<<endl;
}
return 0;
}