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

是个水题...可惜我比赛的时候根本没看这题,赛后二十分钟就a了。这个题甚至直接把递推公式都给你了。那就按题意写一下矩阵就完事了。(我的矩阵多了一维,可以改成6*6的,可是我懒得改了,也没tle。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<map>
#include<stack>
#include<string>
#include<algorithm>
#include<cmath>
#define rg register
#define il inline
using namespace std;
typedef long long ll;
ll read(){
    ll ans = 0,flag = 1; char ch;while((ch=getchar())<'0'||ch>'9') if(ch =='-') flag=-1;ans = ch ^ 48;while((ch=getchar())>='0'&&ch<='9') ans=(ans<<3)+(ans<<1)+(ch^48);return flag*ans;}
void WRI(ll x){if(x<0){ putchar('-');x=-x; }if(x>9) WRI(x/10);putchar(x%10+'0');}
void write(int x,char o){ WRI(x),putchar(o); }
const ll mod=123456789;
struct  matrix{
    ll val[7][7];
};
matrix stdm={
    1,2,0,1,1,1,1,
    1,0,0,0,0,0,0,
    0,1,0,0,0,0,0,
    0,0,0,1,1,1,1,
    0,0,0,0,1,2,3,
    0,0,0,0,0,1,3,
    0,0,0,0,0,0,1
};
matrix mul(matrix a,matrix b){
    matrix ans;
    for(rg int i=0;i<7;i++){
        for(rg int j=0;j<7;j++){
            ans.val[i][j]=0;
            for(rg int k=0;k<7;k++){
                ans.val[i][j]=(ans.val[i][j]+(a.val[i][k]*b.val[k][j])%mod)%mod;
            }
        }
    }
    return ans;
}
matrix mpow(matrix a,ll b){
    matrix ans;
    for(rg int i=0;i<7;i++){for(rg int j=0;j<7;j++) if(i==j)ans.val[i][j]=1;else ans.val[i][j]=0;}
    while(b){
        if(b&1) ans=mul(ans,a);
        a=mul(a,a);
        b>>=1;
    }
    return ans;
}
int main(){
    ll t=read();
    ll x[]={31,2,1,27,27,9,1};
    while(t--){
        ll now=read(),sum=0;
        if(now<=3) printf("%lld\n",x[3-now]);
        else{
            matrix ans=mpow(stdm,now-3);
            for(rg int i=0;i<7;i++){
                sum=(sum+(ans.val[0][i]*x[i])%mod)%mod;
            }
            printf("%lld\n",sum);
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/ffscas/article/details/88603818