HDU6172-Array Challenge

Array Challenge

                                                                      Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 153428/153428 K (Java/Others)
                                                                                                Total Submission(s): 418    Accepted Submission(s): 223


Problem Description
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.
 

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
 

Source
 

Recommend
liuyiding
 

解题思路:看网上的题解,发现居然是可以猜出来的,太菜,既不会推也不会猜

f2=31,f3=197,f4=1255,f5=7997,f6=50959

h3=35,h4=190,h5=1267,h6=7862

可以发现f和h的递推结果很像,根据h的递推式可以猜出f的递推式为fn=4*fn-1+17*fn-2-12*fn-3,然后矩阵快速幂就可以解决了


#include <iostream>  
#include <cstdio>  
#include <string>  
#include <cstring>  
#include <algorithm>  
#include <queue>  
#include <vector>  
#include <set>  
#include <stack>  
#include <map>  
#include <climits>  
#include <functional>  

using namespace std;

#define LL long long  
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;

int n, m, k;

struct Matrix
{
    LL v[5][5];
    Matrix()
    {
        memset(v, 0, sizeof v);
    }
} dan;

Matrix mul(Matrix a, Matrix b, int d)
{
    Matrix ans;
    for (int i = 0; i < d; i++)
        for (int j = 0; j < d; j++)
            for (int k = 0; k < d; k++)
                (ans.v[i][k] += (a.v[i][j] * b.v[j][k]) % mod) %= mod;
    return ans;
}

Matrix pow(Matrix a, LL k, int d)
{
    Matrix ans = dan;
    while (k)
    {
        if (k & 1) ans = mul(ans, a, d);
        k >>= 1;
        a = mul(a, a, d);
    }
    return ans;
}

int main()
{
    int t;
    LL n;
    scanf("%d", &t);
    while (t--)
    {
        scanf("%lld", &n);
        if (n == 2) { printf("31\n"); continue; }
        else if (n == 3) { printf("197\n"); continue; }
        else if (n == 4) { printf("1255\n"); continue; }
        dan.v[0][0] = 1255, dan.v[0][1] = 197, dan.v[0][2] = 31;
        Matrix a, ans;
        a.v[0][0] = 4, a.v[1][0] = 17, a.v[2][0] = -12;
        a.v[0][1] = 1, a.v[1][1] = a.v[2][1] = 0;
        a.v[0][2] = a.v[2][2] = 0, a.v[1][2] = 1;
        ans = pow(a, n - 4, 3);
        printf("%lld\n", (ans.v[0][0]+mod)%mod);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值