数列题解
数列题解
题目链接
此题倒不算难,如果不是求平方和,就是裸题了,但就算这样也不算难。
\(a_n=x \times a_{n-1}+ y \times a_{n-2}\)
\(a_n^2=(x \times a_{n-1}+ y \times a_{n-2})^2=x^2 \times a_{n-1}^2+y^2 \times a_{n-2}^2 +2xy \times a_{n-1}a_{n-2}\)
\(a_{n}a_{n-1}=(x \times a_{n-1}+y \times a_{n-2}) \times a_{n-1}=x \times a_{n-1}^2+y \times a_{n-1}a_{n-2}\)
所以我们只要记录平方和\(sum\),及上述三项,矩阵行列式如下:
初始矩阵:
\(\begin{bmatrix}
sum &{a_n}^2 &{a_{n-1}}^2 & a_{n-1}a_{n}
\end{bmatrix}\)
转移矩阵:
\(\begin{bmatrix}
1 & 0 & 0 & 0\\
1 & x & 1 & x\\
0 & y & 0 & 0\\
0 & 2xy & 0 & y
\end{bmatrix}\)
就成了裸的矩阵快速幂了。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=5;
const ll mod=1e9+7;
int t;
ll n,a1,a2,x,y;
struct matrix{ll z[N][N];}p,q,o;
matrix operator * (matrix u,matrix v){
matrix ans=o;
for(int i=0;i<4;++i) for(int j=0;j<4;++j) for(int k=0;k<4;++k) ans.z[i][j]=(ans.z[i][j]+u.z[i][k]*v.z[k][j]%mod)%mod;
return ans;
}
matrix ksm(matrix u,ll v){
matrix ans=u; --v;
while(v){
if(v&1) ans=ans*u;
u=u*u,v>>=1;
}
return ans;
}
inline ll read(){
ll T=0,F=1; char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
return F*T;
}
int main(){
t=read();
while(t--){
n=read(),a1=read(),a2=read(),x=read(),y=read();
if(n==1){printf("%lld\n",a1*a1%mod); continue;}
p.z[0][0]=a1*a1%mod,p.z[0][1]=a2*a2%mod,p.z[0][2]=a1*a1%mod,p.z[0][3]=a1*a2%mod;
q.z[0][0]=1,q.z[1][0]=1,q.z[1][1]=x*x%mod,q.z[2][1]=y*y%mod,q.z[3][1]=2ll*x*y%mod,q.z[1][2]=1,q.z[1][3]=x,q.z[3][3]=y;
p=p*ksm(q,n-1),printf("%lld\n",p.z[0][0]);
}
return 0;
}