奶牛的编号规则:当前奶牛是第n头,那么他的编号就是2倍的第n-2头奶牛的编号加上第n-1头奶牛的编号再加上自己当前的n的三次方为自己的编号.

第一头奶牛为1号,第二头奶牛为2号

第n头奶牛的编号是多少, 答案模123456789

 

题解:给你公式 

很明显这是一道矩阵快速幂的题目

f(n) = f(n-1) + f(n-2) + n^3

(n+1)^3 = n^3 + 3*n^2 +3*n + 1

推出的矩阵为

/*
Algorithm: 矩阵快速幂
Author: anthony1314
Creat Time:
Time Complexity:
*/

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cstring>
#include<cstdio>
//#include<bits/stdc++.h>
#define ll long long
#define maxn 1005
#define mod 123456789LL
#define line printf("--------------");
using namespace std;
struct node { //2维6阶矩阵
	ll mapp[7][7];
	void init() { //正对角线初始化为1 其他初始化为0
		memset(mapp, 0, sizeof(mapp));
		for(int i = 0; i < 7; i++) {
			mapp[i][i] = 1;
		}
	}
	void initall() { //全初始化为0
		memset(mapp, 0, sizeof(mapp));
	}
};
node mul(node aa, node bb) {//矩阵相乘
	node ans;
	ans.initall();
	for(int i = 0; i < 6; i++) {
		for(int j = 0; j < 6; j++) {
			for(int k = 0; k < 6; k++) {
				ans.mapp[i][j] += aa.mapp[i][k] * bb.mapp[k][j];
				ans.mapp[i][j] %= mod;
			}
		}
	}
	return ans;
}
node quickpownode(node aa, ll n) {//快速幂
	node ans;
	ans.init();//相当于数字1
	while(n) {
		if(n & 1) {
			ans = mul(aa, ans);
		}
		aa = mul(aa, aa);
		n/=2;
	}
	return ans;
}
int main() {
	ll n;
	/*
	1 1 0 0 0 0
	2 0 0 0 0 0
	1 0 1 0 0 0
	0 0 1 1 0 0
	0 0 1 2 1 0
	0 0 1 3 3 1
	*/
	node tmp;
	tmp.initall();
	tmp.mapp[0][0] =tmp.mapp[0][1] =tmp.mapp[2][0] =tmp.mapp[2][2]=tmp.mapp[3][2] =tmp.mapp[3][3] =tmp.mapp[4][2]=tmp.mapp[4][4] =tmp.mapp[5][2] =tmp.mapp[5][5] = 1;
	tmp.mapp[1][0] = tmp.mapp[4][3] = 2;
	tmp.mapp[5][3] = tmp.mapp[5][4] = 3;
	int t;
	cin>>t;
	while(t--) {
		cin>>n;
		node tt = quickpownode(tmp, n-2);
		node ans;
		ans.initall();
		/*
		2 1 n^3 3*n^2 n^2 1
		*/
		ans.mapp[0][0] = 2;
		ans.mapp[0][1] = 1;
		ans.mapp[0][2] = 3*3*3;
		ans.mapp[0][3] = 3*3*3;
		ans.mapp[0][4] = 3*3;
		ans.mapp[0][5] = 1;
		node as = mul(ans, tt);
		cout<<as.mapp[0][0]<<endl;
	}

	return 0;
}