HDU 2256(矩阵快速幂&思维)

y = ( 5 + 2 6 ) 1 + 2 x y=(5+2\sqrt{6})^{1+2^x} y=(5+26 )1+2x

c = ( 5 + 2 6 ) , n = 1 + 2 x c=(5+2\sqrt{6}),n=1+2^x c=(5+26 ),n=1+2x

y = c n ( m o d M ) y=c^n\pmod{M} y=cn(modM)

⌊ ( 2 + 3 ) 2 n ⌋ ( m o d 1024 ) \lfloor(\sqrt{2}+\sqrt{3})^{2n}\rfloor\pmod{1024} (2 +3 )2n(mod1024)

= ( 5 + 2 6 ) n ( m o d 1024 ) =(5+2\sqrt{6})^n\pmod{1024} =(5+26 )n(mod1024)

f ( n ) = ( 5 + 2 6 ) n = A n + 6 B n f(n)=(5+2\sqrt{6})^n=A_n+\sqrt{6}B_n f(n)=(5+26 )n=An+6 Bn

f ( n − 1 ) = A n − 1 + 6 B n − 1 f(n-1)=A_{n-1}+\sqrt{6}B_{n-1} f(n1)=An1+6 Bn1

f ( n ) = ( 5 + 2 6 ) f ( n − 1 ) = ( 5 A n − 1 + 12 B n − 1 ) + 6 ( 2 A n − 1 + 5 B n − 1 ) f(n)=(5+2\sqrt{6})f(n-1)=(5A_{n-1}+12B_{n-1})+\sqrt{6}(2A_{n-1}+5B_{n-1}) f(n)=(5+26 )f(n1)=(5An1+12Bn1)+6 (2An1+5Bn1)

所以 [ A n B n ] = [ A n − 1 B n − 1 ] [ 5 2 12 5 ] \begin{bmatrix}A_{n}& B_{n}\end{bmatrix}=\begin{bmatrix}A_{n-1}& B_{n-1}\end{bmatrix}\begin{bmatrix}5&2\\ 12& 5 \end{bmatrix} [AnBn]=[An1Bn1][51225]

A 1 = 5 , B 1 = 2 A_1=5,B_1=2 A1=5,B1=2

所以可以快速幂求出 A n , B n A_n,B_n An,Bn

( 5 + 2 6 ) n = A n + 6 B n (5+2\sqrt{6})^n=A_n+\sqrt{6}B_n (5+26 )n=An+6 Bn

( 5 − 2 6 ) n = A n − 6 B n < 1 (5-2\sqrt{6})^n=A_{n}-\sqrt{6}B_{n}<1 (526 )n=An6 Bn<1

所以 ( 5 + 2 6 ) n + ( 5 − 2 6 ) n = 2 A n (5+2\sqrt{6})^n+(5-2\sqrt{6})^n=2A_n (5+26 )n+(526 )n=2An

所以 ⌊ ( 5 + 2 6 ) n ⌋ = 2 A n − 1 \lfloor(5+2\sqrt{6})^n\rfloor=2A_n-1 (5+26 )n=2An1

时间复杂度: O ( 8 l o g n ) O(8logn) O(8logn)

code

// Problem: Problem of Precision
// Contest: HDOJ
// URL: http://acm.hdu.edu.cn/showproblem.php?pid=2256
// Memory Limit: 32 MB
// Time Limit: 1000 ms
// Date: 2021-04-12 14:07:54
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=1e3+5,M=2e4+5,inf=0x3f3f3f3f,mod=1024;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define IOS ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\n",a[n]); 
}

struct mtx{
	int a[3][3];
	int r,c;
	mtx(int rr,int cc,int p=0){
		r=rr,c=cc;
		mst(a,0);
		if(p==1) for(int i=1;i<=rr;i++) a[i][i]=1;
	}
	mtx operator *(const mtx &b)const{
		mtx m(r,b.c);
			for(int i=1;i<=r;i++)
			for(int j=1;j<=m.c;j++)
				for(int k=1;k<=c;k++)
			m.a[i][j]=(m.a[i][j]+a[i][k]*b.a[k][j])%mod;
		return m;
	}
};
mtx ksm(int n){
	mtx ans(2,2,1),m(2,2);
	m.a[1][1]=5;m.a[1][2]=2;m.a[2][1]=12,m.a[2][2]=5;
	while(n){
		if(n&1) ans=ans*m;
		m=m*m;
		n>>=1;
	}
	return ans;
}
void solve(){
	//think twice code once
	int t;scanf("%d",&t);
	while(t--){
		int n;
		scanf("%d",&n);
		mtx ans=ksm(n-1);
		mtx tmp(1,2);
		tmp.a[1][1]=5,tmp.a[1][2]=2;
		ans=tmp*ans;
		int res=(2*ans.a[1][1]-1)%mod;
		printf("%d\n",res);
	}
}
int main(){
	solve();
	return 0;
}