数列题解

数列题解

题目链接
此题倒不算难,如果不是求平方和,就是裸题了,但就算这样也不算难。
\(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;
}
posted @ 2019-11-11 18:00  lsoi_ljk123  阅读(132)  评论(0编辑  收藏  举报