HDU 6172 Array Challenge(矩阵快速幂)

52 篇文章 0 订阅

Description

h0=2,h1=3,h2=6,hn=4hn1+17hn212hn316 h 0 = 2 , h 1 = 3 , h 2 = 6 , h n = 4 h n − 1 + 17 h n − 2 − 12 h n − 3 − 16

bn=3hn+1hn+9hn+1hn1+9h2n+27hnhn118hn+1126hn81hn1+192,n>0 b n = 3 h n + 1 h n + 9 h n + 1 h n − 1 + 9 h n 2 + 27 h n h n − 1 − 18 h n + 1 − 126 h n − 81 h n − 1 + 192 , n > 0

an=bn+4n,n>0 a n = b n + 4 n , n > 0

an,n>1 ⌊ a n ⌋ , n > 1

Input

第一行一整数 T T 表示用例组数,每组用例输入一整数n (1T1000,1<n1015) ( 1 ≤ T ≤ 1000 , 1 < n ≤ 10 15 )

Output

an ⌊ a n ⌋ ,结果模 109+7 10 9 + 7

Sample Input

3
4
7
9

Sample Output

1255

Solution

先给出一个结论,若 fn=afn1+bfn2 f n = a f n − 1 + b f n − 2 ,则 f2n+1afn+1fnbf2n=b(f2nafnfn1bf2n1)=(b)n(f21af1f0bf20) f n + 1 2 − a f n + 1 f n − b f n 2 = − b ( f n 2 − a f n f n − 1 − b f n − 1 2 ) = ( − b ) n ( f 1 2 − a f 1 f 0 − b f 0 2 )

直接将 fn+1=afn+bfn1 f n + 1 = a f n + b f n − 1 代入即可证明

考虑化简 bn b n ,有 bn=3(hn+1+3hn8)(hn+3hn18)+6hn+130hn9hn1 b n = 3 ( h n + 1 + 3 h n − 8 ) ( h n + 3 h n − 1 − 8 ) + 6 h n + 1 − 30 h n − 9 h n − 1

fn=hn+3hn18 f n = h n + 3 h n − 1 − 8 ,配凑 hn=4hn1+17hn212hn316 h n = 4 h n − 1 + 17 h n − 2 − 12 h n − 3 − 16 fn=7fn14fn2 f n = 7 f n − 1 − 4 f n − 2

h0=2,h1=3,h2=6 h 0 = 2 , h 1 = 3 , h 2 = 6 f1=1,f2=7 f 1 = 1 , f 2 = 7 ,定义 f0=0 f 0 = 0 则同样的有 f2=7f14f0 f 2 = 7 f 1 − 4 f 0 ,故由上面的结论可知 f2n+17fn+1fn+4f2n=4n f n + 1 2 − 7 f n + 1 f n + 4 f n 2 = 4 n

进而 an=3fn+1fn+4n+6hn+130hn9hn1=(fn+12fn)2+6hn+130hn9hn1 a n = 3 f n + 1 f n + 4 n + 6 h n + 1 − 30 h n − 9 h n − 1 = ( f n + 1 − 2 f n ) 2 + 6 h n + 1 − 30 h n − 9 h n − 1

不断展开 hn+1 h n + 1 可以证明 0<6hn+130hn9hn1<2fn+14fn+1,n>1 0 < 6 h n + 1 − 30 h n − 9 h n − 1 < 2 f n + 1 − 4 f n + 1 , n > 1 ,故有 (fn+12fn)2<an<(fn+12fn+1)2 ( f n + 1 − 2 f n ) 2 < a n < ( f n + 1 − 2 f n + 1 ) 2 ,进而有 an=fn+12fn=7an14an2 ⌊ a n ⌋ = f n + 1 − 2 f n = 7 ⌊ a n − 1 ⌋ − 4 ⌊ a n − 2 ⌋ ,矩阵快速幂即可

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
typedef long long ll;
using namespace std;
const int INF=0x3f3f3f3f,maxn=5;
const ll mod=1000000007;
struct Mat
{
    ll mat[maxn][maxn];//矩阵 
    int row,col;//矩阵行列数 
};
Mat mod_mul(Mat a,Mat b,int p)//矩阵乘法 
{
    Mat ans;
    ans.row=a.row;
    ans.col=b.col;
    memset(ans.mat,0,sizeof(ans.mat));
    for(int i=0;i<ans.row;i++)        
        for(int k=0;k<a.col;k++)
            if(a.mat[i][k])
                for(int j=0;j<ans.col;j++)
                {
                    ans.mat[i][j]+=a.mat[i][k]*b.mat[k][j]%mod;
                    ans.mat[i][j]%=p;
                }
    return ans;
}
Mat mod_pow(Mat a,ll k,int p)//矩阵快速幂 
{
    Mat ans;
    ans.row=a.row;
    ans.col=a.col;
    for(int i=0;i<a.row;i++)
        for(int j=0;j<a.col;j++)
            ans.mat[i][j]=(i==j);
    while(k)
    {
        if(k&1)ans=mod_mul(ans,a,p);
        a=mod_mul(a,a,p);
        k>>=1;
    }
    return ans;
}
Mat A,B;
int main()
{
    A.col=A.row=2;
    A.mat[0][0]=7,A.mat[0][1]=mod-4,A.mat[1][0]=1,A.mat[1][1]=0;
    int T;
    ll n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%I64d",&n);
        if(n==2)printf("31\n");
        else if(n==3)printf("197\n");
        else
        {
            B=mod_pow(A,n-3,mod);
            ll ans=197ll*B.mat[0][0]%mod+31ll*B.mat[0][1]%mod;
            ans=(ans%mod+mod)%mod;
            printf("%I64d\n",ans);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值