1. 程式人生 > >HDU - 2256 矩陣快速冪 帶根號的遞推

HDU - 2256 矩陣快速冪 帶根號的遞推

mat cpp matrix 有一個 rac 分析 eof rhs oid

題意:求$ [(\sqrt{2}+\sqrt{3})^{2n}] mod 1024 $
分析: 把指數的2帶入 原式等於 $ [(5+2\sqrt{6})^n] $
有一個重要的結論是n次運算後其結果最終形式也是$ a_n+b_n\sqrt{6} $ 的形式
記最終的解$ F(n) = a_n+b_n\sqrt{6} $
$ F(n-1) = a_{n-1}+b_{n-1}\sqrt{6} $
$\frac{F(n)}{F(n-1)} = 5+2\sqrt{6} $
$ F(n) = (5+2\sqrt{6})F(n-1) $
$ F(n) = (5+2\sqrt{6})a_{n-1}+(5\sqrt{6}+12)b_{n-1} $
$ F(n) = a_n+b_n\sqrt{6} $
$ a_n = (5+2\sqrt{6})a_{n-1} $, $ b_n\sqrt{6} = (5\sqrt{6}+12)b_{n-1} $
$ a_n+b_n\sqrt{6} = (5a_{n-1}+12b_{n-1})+(2a_{n-1}+5b_{n-1})\sqrt{6} $

inline ll mod(ll a){return a%MOD;}
struct Matrix{
    ll mt[22][22],r,c;
    void init(int rr,int cc,bool flag=0){
        r=rr;c=cc;
        memset(mt,0,sizeof mt);
        if(flag) rep(i,1,r) mt[i][i]=1;
    }
    Matrix operator * (const Matrix &rhs)const{
        Matrix ans; ans.init(r,rhs.c);
        rep(i,1
,r){ rep(j,1,rhs.c){ int t=max(r,rhs.c); rep(k,1,t){ ans.mt[i][j]+=mod(mt[i][k]*rhs.mt[k][j]); ans.mt[i][j]=mod(ans.mt[i][j]); } } } return ans; } }; Matrix fpw(Matrix A,int
n){ Matrix ans;ans.init(A.r,A.c,1); while(n){ if(n&1) ans=ans*A; n>>=1; A=A*A; } return ans; } int bas[3][3]={ {0,0,0}, {0,5,12}, {0,2,5}, }; int bas2[]={0,5,2}; int main(){ Matrix A;A.init(2,2); rep(i,1,2) rep(j,1,2) A.mt[i][j]=bas[i][j]; Matrix b; b.init(2,1); rep(i,1,2) b.mt[i][1]=bas2[i]; int T=read(); while(T--){ int n=read(); Matrix res=fpw(A,n-1); res=res*b; ll ans=mod(2*res.mt[1][1]-1+MOD); println(ans); } return 0; }

HDU - 2256 矩陣快速冪 帶根號的遞推