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;
}