矩阵快速幂 Count

附dalao博客地址:https://blog.csdn.net/zcy19990813/article/details/88720995

首先还是先看一下什么是快速幂 https://www.cnblogs.com/CXCXCXC/p/4641812.html

矩阵快速幂讲解 https://blog.csdn.net/wust_zzwh/article/details/52058209

                                             Count

Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

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行,每行一个正整数表示所求的答案

Sample Input

5

3 6 9 12 15

Sample Outpu

31

700

7486

64651

527023

首先,根据题意,可以推出来一个递推公式,F(n)=F(n-1)+2F(n-2)+n^3

令n=n+1,得出 F(n+1)=F(n)+2F(n1)+(n+1)^3,化简得:F(n+1)=F(n)+2F(n1)+n^3+3n^2+3n+1

还是看图吧

图片链接 :  https://blog.csdn.net/zcy19990813/article/details/88720995

A^(n-2) * B2 的 a[0][0] 即为我们要求的答案

//struct A
//{
//    ll x,y;
//    bool operator < (const A & a) const
//    {
//        return x>a.x;
//    }
//};
//priority_queue <A> q;
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#define eps 0.0000000001
#define mem(a) memset(a,0,sizeof(a))
#define maxx 1e10
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
//priority_queue<int,vector<int>,greater<int> > q;
#define mod 123456789
const int maxn=6;
struct Matric
{
    ll a[maxn][maxn];
    void init()
    {
        mem(a);
        for(int i=0;i<maxn;i++)
            a[i][i]=1;
    }
};

Matric mul(Matric x,Matric y)
{
    Matric ans;
    for(int i=0;i<maxn;i++)
    {
        for(int j=0;j<maxn;j++)
        {
            ans.a[i][j]=0;
            for(int k=0;k<maxn;k++)
            {
                ans.a[i][j]+=x.a[i][k]*y.a[k][j];
                ans.a[i][j]%=mod;
            }
        }
    }
    return ans;
}


Matric qpow(Matric x,ll n)
{
    Matric ans;
    ans.init();
    while(n)
    {
        if(n%2==1)
            ans=mul(ans,x);
        x=mul(x,x);
        n/=2;
    }
    return ans;
}

int main()
{
    int T;cin>>T;
    while(T--)
    {
        ll n;
        Matric B2,ans;
        Matric A;
        ll t[maxn][maxn]={
        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};
        for(int i=0;i<maxn;i++)
            for(int j=0;j<maxn;j++)
              A.a[i][j]=t[i][j];
        mem(B2.a);
        B2.a[0][0]=2;
        B2.a[1][0]=1;
        B2.a[2][0]=8;
        B2.a[3][0]=4;
        B2.a[4][0]=2;
        B2.a[5][0]=1;
        cin>>n;
        if(n==1)
            cout<<"1"<<endl;
        else if(n==2)
            cout<<"2"<<endl;
        else
        {
            ans=qpow(A,n-2);
            ans=mul(ans,B2);
            cout<<ans.a[0][0]<<endl;
        }

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Septembre_/article/details/88724429