HDU6470 Count(矩阵快速幂)

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

Sample Input

5
3
6
9
12
15

Sample Output

31
700
7486
64651
527023

这道题我们在最开始做的时候用Java一边做一边模,但模的数为123456789,如果n为123456788,n的三次方肯定要爆,所以要把n的三次方解决,考虑n3变成(n+1)的三次方

 ,多了3*n的2次方,3n,1

然后就可以构造一个6x6的矩阵[f(n−1),f(n−2),n的三次方,3*n的2次方,3n,1]

解题代码:

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mpmake_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define SZ(x) ((int)(x).size())
typedef vector<int> VI;
typedef long longll;
typedef pair<int,int> PII;
const ll mod=123456789;
llpowmod(lla,ll b) {
    ll res=1;a%=mod; 
    assert(b>=0); 
    for(;b;b>>=1){
        if(b&1)
        res=res*a%mod;
        a=a*a%mod;
    }
    return res;
}
llgcd(lla,ll b) 
{ 
    return b?gcd(b,a%b):a;
}

const int maxn = 6;

int T;
ll n;
struct Matrix{
    ll a[maxn][maxn];
    void init(){    
        memset(a, 0, sizeof(a));
        for(int i=0;i<maxn;++i){
                a[i][i] = 1;
            }
        }
    void Init(){    
        memset(a, 0, sizeof(a));
    }
};

Matrix mul(Matrix a, Matrix b){
    Matrix 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] += a.a[i][k] * b.a[k][j];
            ans.a[i][j] %= mod; 
            }
        }
    } 
    return ans;
}

Matrix qpow(Matrix a, ll n){
    Matrix ans;
    ans.init();
    while(n){
        if(n&1) ans = mul(ans, a);
        a = mul(a, a);
        n /= 2;
    } 
    return ans;
}

void output(Matrix a){
    for(int i=0;i<maxn;++i){
        for(int j=0;j<maxn;++j){
            cout<<a.a[i][j] << " ";
        }
        cout<<endl;
    }
}
int main(int argc, char const *argv[])
{
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    Matrix tmp;
    tmp.Init();
    tmp.a[0][0] = 1;
    tmp.a[0][1] = 1; 
    tmp.a[1][0] = 2;
    tmp.a[2][0] = 1;
    tmp.a[2][2] = 1;
    tmp.a[3][2] = 1;
    tmp.a[3][3] = 1;
    tmp.a[4][2] = 1;
    tmp.a[4][3] = 2;
    tmp.a[4][4] = 1;
    tmp.a[5][2] = 1;
    tmp.a[5][3] = 3;
    tmp.a[5][4] = 3;
    tmp.a[5][5] = 1;
    cin>> T;
    while(T--)
    {
        cin>> n;
        Matrix t = qpow(tmp,n-2);
        Matrix ans;
        ans.Init();
        ans.a[0][0] = 2;
        ans.a[0][1] = 1;
        ans.a[0][2] = 3*3*3;
        ans.a[0][3] = 3*3*3;
        ans.a[0][4] = 3*3;
        ans.a[0][5] = 1;
        Matrix as = mul(ans,t);
        cout<<as.a[0][0] <<endl;
    }
    return 0;
}

 

 

 
posted @ 2019-05-14 16:28  里昂静  阅读(357)  评论(0编辑  收藏  举报