的确和题目描述一样,见过这个类型就so easy了
对于这个类型,首先化为二阶通项公式的类型,然后根据特征根反过来推递推方程就行
然而无脑的我还是调了一个晚上,就因为写乘法的时候忘记return了
然后就写了两个版本的,其实并没有多大不同
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
LL inf;
#define N 2
struct matrix
{
LL a[N][N];
void clear()
{
fo(i,0,N-1)
fo(j,0,N-1)
a[i][j]=0;
}
matrix operator*(const matrix b)
{
matrix anss;
fo(i,0,N-1)
fo(j,0,N-1)
{
anss.a[i][j]=0;
fo(k,0,N-1)
{
anss.a[i][j]=(anss.a[i][j]+a[i][k]*b.a[k][j])%inf;
anss.a[i][j]+=inf;anss.a[i][j]%=inf;
}
anss.a[i][j]+=inf;anss.a[i][j]%=inf;
}
return anss;
}
};
matrix I=
{
1,0,
0,1
};
LL a,b,n;
matrix KSM(matrix a,LL b)
{
if(b==0)return I;
if(b==1)return a;
matrix ret=KSM(a,b/2);
ret=ret*ret;
if(b%2)ret=ret*a;
return ret;
}
int main()
{
matrix A,anss;
while(cin>>a>>b>>n>>inf)
{
if(n==1)
{
cout<<(2*a%inf)<<endl;
continue;
}
A.clear();anss.clear();
A.a[0][0]=2*a%inf;
A.a[0][1]=((b%inf-a*a%inf)%inf+inf)%inf;
A.a[1][0]=1;
A.a[1][1]=0;
anss=KSM(A,n-2);
cout<<(((anss.a[0][0]%inf*2*(a*a%inf+b%inf)%inf+2*a%inf*anss.a[0][1]%inf)%inf+inf)%inf)<<endl;
}
return 0;
}
还有就是看起来精简好多的
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define LL long long
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define down(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
LL inf;
#define N 2
struct matrix
{
LL a[N][N];
void clear()
{
fo(i,0,N-1)
fo(j,0,N-1)
a[i][j]=0;
}
matrix operator*(const matrix b)
{
matrix anss;
fo(i,0,N-1)
fo(j,0,N-1)
{
anss.a[i][j]=0;
fo(k,0,N-1)
{
anss.a[i][j]=((anss.a[i][j]+a[i][k]*b.a[k][j])%inf+inf)%inf;
}
}
return anss;
}
};
matrix I=
{
1,0,
0,1
};
LL a,b,n;
matrix KSM(matrix a,LL b)
{
matrix ret=a,p=a;b--;
while(b)
{
if(b&1)
{
ret=ret*p;
b--;
}
p=p*p;
b>>=1;
}
return ret;
}
int main()
{
matrix A,anss;
while(cin>>a>>b>>n>>inf)
{
if(n==1)
{
cout<<(2*a%inf)<<endl;
continue;
}
anss.clear();
A.a[0][0]=2*a;
A.a[0][1]=b-a*a;
A.a[1][0]=1;
A.a[1][1]=0;
anss=KSM(A,n-1);
// cout<<anss.a[0][0]<<' '<<anss.a[0][1]<<endl;
// cout<<anss.a[1][0]<<' '<<anss.a[1][1]<<endl;
LL ans=(anss.a[0][0]*2*a+anss.a[0][1]*2)%inf;
ans+=inf;ans%=inf;
cout<<ans<<endl;
}
return 0;
}