题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4565
这个博客讲的比较好:http://blog.csdn.net/ljd4305/article/details/8987823
题意:给定a,b,,n,m,求Sn
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<climits>
typedef long long ll;
using namespace std;
struct matrix
{
ll m[2][2];
};
matrix a,per,s;
ll A,B,N,M;
void init()//初始化操作
{
per.m[0][0]=1;
per.m[0][1]=0;
per.m[1][0]=0;
per.m[1][1]=1;
s.m[0][0]=((2*((A%M)*(A%M))%M)%M+(2*B)%M)%M;
s.m[0][1]=(2*(A%M))%M;
s.m[1][0]=0;
s.m[1][1]=0;
a.m[0][0]=(2*(A%M))%M;
a.m[0][1]=1;
a.m[1][0]=(((B%M)-((A%M)*(A%M))%M)+M)%M;
a.m[1][1]=0;
}
matrix multi(matrix a,matrix b)//矩阵乘法操作
{
matrix c;
for(ll i=0; i<2; i++)
{
for(ll j=0; j<2; j++)
{
c.m[i][j]=0;
for(ll k=0; k<2; k++)
{
c.m[i][j]+=(a.m[i][k]*b.m[k][j])%M;
c.m[i][j]%=M;
}
c.m[i][j]%=M;
}
}
return c;
}
matrix power(ll k)//矩阵求幂操作,二分的思想
{
matrix p=a,ans=per;
while(k)
{
if(k&1)ans=multi(ans,p);
k=k/2;
p=multi(p,p);
}
return ans;
}
int main()
{
//freopen("C:\\Users\\Administrator\\Desktop\\in.txt" , "r" , stdin);
matrix ans;
while(cin>>A>>B>>N>>M)
{
init();
if(N==1)//等于1,2,时直接输出就可以
{
cout<<(2*(A%M))%M<<endl;
continue;
}
else if(N==2)
{
cout<<((2*(A%M)*(A%M))%M+(2*(B%M))%M)%M<<endl;
continue;
}
else
{
ans=power(N-2);
ans=multi(s,ans);
cout<<ans.m[0][0]<<endl;
}
}
return 0;
}