Array Challenge 2017 多校10 矩陣快速冪


Array Challenge  

There’s an array that is generated by following rule.
h0=2,h1=3,h2=6,hn=4hn−1+17hn−2−12hn−3−16
And let us define two arrays bnandan as below.
iibn=n+1hn+9hn+1hn−1+9hn2+27hnhn−1−18hn+1−126hn−81hn−1+192(n>0)
an=bn+4n
Now, you have to print ⌊√(an)⌋ , n>1.
Your answer could be very large so print the answer modular 1000000007.  

Input

The first line of input contains T (1 <= T <= 1000) , the number of test cases.
Each test case contains one integer n (1 < n <= 1015) in one line.

Output

For each test case print &#8970;√(a_n )&#8971; modular 1000000007.

Sample Input

3
4
7
9

Sample Output

1255
324725
13185773




題意很簡單了,就是求 { sqrt(a[n]) },但是公式怎麼推出來就很難了,官方題解如此:


表示看半天雖然推出了但是很複雜,就搜了一下別人的博客,發現一個玄學的解答,具體思路就是打個表,然後瞎貓碰死耗子,直接假設 sqrt(a(n))  滿足Hn 的遞推式,結果還真是的......(ORZ

點擊打開鏈接

設  要求的爲 Fn, Fn=4Fn-1 + 17Fn-2 -12Fn-3;

                   F2=31;F3=197; F4=1225;F5=7997;

接下來就是矩陣快速冪了。 

Fn          4 1 0       Fn

Fn-1       17 0 1      Fn-1

Fn-2       -12 0 0     Fn-2


#pragma comment(linker, "/STACK:1024000000,1024000000")
//#include <bits/stdc++.h>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#define maxn 10010
#define INF 0x3f3f3f3f
#define MOD 1000000007
#define ll long long
using namespace std;


struct Node
{
    ll a[5][5];
    Node()
    {
        memset(a,0,sizeof a);
    }
};
Node Mul(Node A,Node B)
{
    Node C;
    for(int i=1;i<=3;i++)
    {
        for(int j=1;j<=3;j++)
        {
            for(int k=1;k<=3;k++)
                C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j]+MOD)%MOD;
        }
    }
    return C;
}
Node Pow(Node A,ll p)
{
    Node B;
    B.a[1][1]=B.a[2][2]=B.a[3][3]=1;
    while(p)
    {
        if(p&1) B=Mul(B,A);
        A=Mul(A,A);
        p>>=1;
    }
    return B;
}

int main()
{
    ll n,T;
    scanf("%lld",&T);
    while(T--)
    {
        scanf("%lld",&n);
        if(n == 2) puts("31");
        else if(n == 3) puts("197");
        else if(n == 4) puts("1255");
        else if(n == 5) puts("7997");
        else
        {
            Node A;
            memset(A.a,0,sizeof (A.a));
            A.a[1][1]=4,A.a[1][2]=17,A.a[1][3]=-12;
            A.a[2][1]=1,A.a[3][2]=1;
            Node C=Pow(A,n-4);
            ll ans=(C.a[1][1]*1255%MOD+C.a[1][2]*197%MOD+C.a[1][3]*31%MOD+MOD)%MOD;
            printf("%lld\n",ans);
        }
    }
    return  0;
}





 



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章