/*
f(n)=3*f(n-1)+2*f(n-2);
构造二维矩阵
一:
求转置矩阵
f(n) f(n-1) f(n-1) f(n-2) 3 1
= *
( ) ( ) ( ) ( ) 2 0
求初始矩阵
f(n) f(n-1) 3 1
f(n-1) f(n-2) 1 1
此形势下 求值为 初始矩阵*转置矩阵
转置矩阵A 初始矩阵B
matrix a1,a2;
b1=qpow(A,n-2);
a1=multip(B,b1);注意这里一定要和上面对应
二:
求转置矩阵
f(n) ( ) 3 2 f(n-1) ( )
= *
f(n-1) ( ) 1 0 f(n-2) ( )
求初始矩阵
f(n) f(n-1) 3 1
f(n-1) f(n-2) 1 1
此形势下 求值为 转置矩阵*初始矩阵
转置矩阵A 初始矩阵B
matrix a1,a2;
b1=qpow(A,n-2);
a1=multip(b1,B);注意这里一二区别
*/
/*
矩阵快速幂
*/
/*
*/
/*
F(n+1)=F(n)+2*F(n-1)+n^3+3*n^2+3*n+1
转置矩阵
F(n+1) F(n) 1 2 1 3 3 1
F(n) F(n-1) 1 0 0 0 0 0
(n+1)^3 (n)^3 0 0 1 3 3 1
(n+1)^2 (n)^2 0 0 0 1 2 1
(n+1) (n) 0 0 0 0 1 1
1 1 0 0 0 0 0 1
*/
#include <cstdio>
#include <cstring>
#include <string>
#include <set>
#include <cmath>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
//const long long mod=2147493647;
#define ll long long
using namespace std;
const long long N=6;
#define mod 123456789
struct matrix
{
long long a[N][N];
matrix()
{
memset(a,0,sizeof(a));
}
void init()
{
memset(a,0,sizeof(a));
for(long long i=0;i<N;i++)
{
a[i][i]=1;
}
}
};
matrix multip(matrix x,matrix y)
{//相乘
matrix temp;
for(long long i=0;i<N;i++)
{
for(long long j=0;j<N;j++)
{
for(long long k=0;k<N;k++)
{
temp.a[i][j]=(temp.a[i][j]%mod+x.a[i][k]*y.a[k][j]%mod)%mod;
}
}
}
return temp;
}
matrix qpow(matrix M,long long k)
{//矩阵快速幂
matrix temp;
temp.init();
while(k)
{
if(k&1)
{
temp=multip(temp,M);
}
k>>=1;
M=multip(M,M);
}
return temp;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long n;
scanf("%lld",&n);
if(n==1)
{
printf("1\n");
}
else if(n==2)
{
printf("2\n");
}
else
{
ll zhuanzhi[6][6]=
{
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,
};
matrix A,B;
for(ll i=0;i<N;i++)
{
for(ll j=0;j<N;j++)
{
B.a[i][j]=zhuanzhi[i][j];
}
}
A.a[0][0]=2;
A.a[1][0]=1;
//先是F(2)的值,然后是F(n)的值
A.a[2][0]=8;
A.a[3][0]=4;
A.a[4][0]=2;
A.a[5][0]=1;
//根据F(n+1)=F(n)+2*F(n-1)+n^3+3*n^2+3*n+1;将n=2代入
matrix p=qpow(B,n-2);
matrix ans=multip(p,A);
printf("%lld\n",ans.a[0][0]);
}
}
return 0;
}