HDU-6470 矩阵快速幂

题目衔接:http://acm.hdu.edu.cn/showproblem.php?pid=6470

Count

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 565    Accepted Submission(s): 226


 

Problem Description

Farmer John有n头奶牛.
某天奶牛想要数一数有多少头奶牛,以一种特殊的方式:
第一头奶牛为1号,第二头奶牛为2号,第三头奶牛之后,假如当前奶牛是第n头,那么他的编号就是2倍的第n-2头奶牛的编号加上第n-1头奶牛的编号再加上自己当前的n的三次方为自己的编号.
现在Farmer John想知道,第n头奶牛的编号是多少,估计答案会很大,你只要输出答案对于123456789取模.

 

Input

第一行输入一个T,表示有T组样例
接下来T行,每行有一个正整数n,表示有n头奶牛 (n>=3)
其中,T=10^4,n<=10^18

 

Output

共T行,每行一个正整数表示所求的答案

扫描二维码关注公众号,回复: 5758071 查看本文章

 

Sample Input

 

5 3 6 9 12 15

 

Sample Output

 

31 700 7486 64651 527023

 

Source

“字节跳动-文远知行杯”广东工业大学第十四届程序设计竞赛

 题目大意就不在描述了,思路:看到数据范围,1e18非常大的一个数,暴力肯定不行,打表也有困难,题目中也直接给了公式:F(n)=2F(n-2)+F(n-1)+n^3

所以我们用矩阵快速幂来做;

首先构造矩阵得到转移矩阵

1 2 1 3 3 1

1 0 0 0 0 0

0 0 1 3 3 1

0 0 0 1 2 1

0 0 0 0 1 1

0 0 0 0 0 1

初始矩阵为:2 1 8 4 2 1

所以套用模板得:

代码:

#include<map>
#include<set>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll  long long
#define inf 0x3f3f3f3
#define esp 1e-8
#define bug {printf("mmp\n");}
#define mm(a,b) memset(a,b,sizeof(a))
const int maxn=6;
const double pi=acos(-1.0);
const int N=1e9+100;
const int mod=123456789;

struct node
{
    ll A[maxn][maxn];
} r;
node init=
{
    1,2,1,3,3,1,
    1,0,0,0,0,0,
    0,0,1,3,3,1,
    0,0,0,1,2,1,
    0,0,0,0,1,1,
    0,0,0,0,0,1
};
node matrix(node m,node r)
{
    node c;
    for(int i=0; i<maxn; i++)
    {
        for(int j=0; j<maxn; j++)
        {
            c.A[i][j]=0;
            for(int k=0; k<maxn; k++)
            {
                c.A[i][j]=(c.A[i][j]+(m.A[i][k]*r.A[k][j])%mod)%mod;
            }
        }
    }
    return c;
}
node powmi(node a,ll k)
{
    node res;
    memset(res.A,0,sizeof(res.A));
    for(int i=0; i<maxn; i++)
        res.A[i][i]=1;
    while(k)
    {
        if(k&1)
            res=matrix(res,a);
        k>>=1;
        a=matrix(a,a);
    }
    return res;
}

int main()
{
    int test;
    scanf("%d",&test);
    while(test--)
    {
        ll n;
        scanf("%lld",&n);
        node aa=powmi(init,n-2);
        ll res[]= {2,1,8,4,2,1},sum=0;
        for(int i=0; i<maxn; i++)
        {
            sum=(sum+(aa.A[0][i]*res[i])%mod)%mod;
        }
        printf("%lld\n",sum);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lee371042/article/details/88693013