题目链接:HDU 3306
题意:求S(n)=∑(a(n)^2),其中a(i)=x*a(i-1)+y*a(i-2),且a(0)=1,a(1)=1。
分析:
- 已知:a(i)=x*a(i-1)+y*a(i-2) ①
- 平方得:a(n)^2=(x^2)*(a(i-1)^2)+(y^2)*(a(i-2)^2)+2xy*a(i-1)*a(i-2) ②
- a(i-1)*a(i-2) ③
不难发现② 式子中除了 ③ 都是可以通过关系矩阵递推的,因此单独考虑③
- a(i)*a(i-1)=(x*a(i-1)+y*a(i-2))*a(i-1)=x*(a(i-1)^2)+y*a(i-1)*a(i-2) ④
有了④的递推式我们可以构造如下矩阵:
- s(i)=s(i-1)+a(i)^2
以下是代码
#include <bits/stdc++.h> #define ll long long using namespace std; const int N=3e5+10; const int maxn=10; const ll Mod=10007; ll tmp[maxn][maxn]; void multi(ll a[][maxn],ll b[][maxn],int n)//n是矩阵大小 { int i,j,k; memset(tmp,0,sizeof tmp); for(i=1;i<=n;i++) for(j=1;j<=n;j++) for(k=1;k<=n;k++) { tmp[i][j]+=a[i][k]*b[k][j]; tmp[i][j]%=Mod; } for(i=1;i<=n;i++) for(j=1;j<=n;j++) a[i][j]=tmp[i][j]; } ll res[maxn][maxn]; void Pow(ll a[][maxn],ll m,int n)// a 是初始矩阵 res是答案数组 m是幂,n是矩阵大小 { for(int i=1;i<maxn;i++) for(int j=1;j<maxn;j++) res[i][j]=(i==j); while(m) { if(m&1) multi(res,a,n); //res=res*a; multi(a,a,n); //a=a*a m>>=1; } } void Show(int n) { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cout<<res[i][j]<<" "; } cout<<endl; } } ll a[maxn][maxn]; int main() { ll n,x,y; while(~scanf("%lld%lld%lld",&n,&x,&y)) { x%=Mod;y%=Mod; a[1][1]=1;a[1][2]=x*x;a[1][3]=y*y;a[1][4]=2*x*y; a[2][1]=0;a[2][2]=x*x;a[2][3]=y*y;a[2][4]=2*x*y; a[3][1]=0;a[3][2]=1 ;a[3][3]=0 ;a[3][4]=0 ; a[4][1]=0;a[4][2]=x ;a[4][3]=0 ;a[4][4]=y ; Pow(a,n-1,4); ll ans=0; ans=(ans+2*res[1][1])%Mod; ans=(ans+res[1][2])%Mod; ans=(ans+res[1][3])%Mod; ans=(ans+res[1][4])%Mod; printf("%lld\n",ans); } return 0; } /* */