2017 Multi-University Training Contest 10 1002 Array Challenge HDU 6172(找规律 矩阵快速幂)

题意:There’s an array that is generated by following rule.
h0=2,h1=3,h2=6,hn=4hn1+17hn212hn316
And let us define two arrays bnandan as below.
bn=3hn+1hn+9hn+1hn1+9h2n+27hnhn118hn+1126hn81hn1+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.


思路:这规律都能找到。。。也是厉害的。。。

摘自博客:点击打开链接

解题思路:fn=an,写出前几项f2=31,f3=197,f4=1255,f5=7997,f6=50959 
h3=35,h4=190,h5=1267,h6=7862 
可以发现fnhn的递推结果很像, 
于是根据hn的递推关系猜测fn=4fn1+17fn212fn3 
是一个线性递推式,用矩阵快速幂。


代码:

#include
#include
#include
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
struct node
{
    ll s[5][5];
};

node mul(node a, node b)
{
    node t;
    memset(t.s, 0, sizeof(t.s));
    for(int i = 1; i <= 3; i++)
        for(int j = 1; j <= 3; j++)
            for(int k = 1; k <= 3; k++)
                t.s[i][j] = (t.s[i][j]+a.s[i][k]*b.s[k][j]+mod)%mod;
    return t;
}

node mt_pow(node p, ll q)
{
    node res;
    memset(res.s, 0, sizeof(res.s));
    for(int i = 1; i <= 3; i++) res.s[i][i] = 1;
    while(q)
    {
        if(q%2) res = mul(res, p);
        p = mul(p, p);
        q /= 2;
    }
    return res;
}

int main(void)
{
    int t;
    cin >> t;
    while(t--)
    {
        ll n;
        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 base;
            memset(base.s, 0, sizeof(base.s));
            base.s[1][1] = 4, base.s[1][2] = 17, base.s[1][3] = -12;
            base.s[2][1] = 1, base.s[3][2] = 1;
            node ans = mt_pow(base, n-4);
            ll res = (ans.s[1][1]*1255%mod+ans.s[1][2]*197%mod+ans.s[1][3]*31%mod+mod)%mod;
            printf("%lld\n", res);
        }
    }
    return 0;
}


你可能感兴趣的:(找规律,矩阵)