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

来源:互联网 发布:淘宝免费店招图片 编辑:程序博客网 时间:2024/06/04 19:35
题意: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<iostream>#include<cstdio>#include<cstring>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;}


阅读全文
1 0
原创粉丝点击