题目大意:给出n,求(sqrt(2)+sqrt(3))^(2n),多组数据。
题目分析:(sqrt(2)+sqrt(3))^2=5+2*sqrt(6)。设(5+2*sqrt(6))^n=An+Bn*sqrt(6),(5+2*sqrt(6))^(n-1)=An-1+Bn-1*sqrt(6)则易得An=5*An-1+12*Bn-1,Bn=2*An-1+5*Bn-1,写成矩阵快速幂的形式可以在log(n)的时间内求出。
由于0<5-2*sqrt(6)<1,故0<(5-2*sqrt(6))^n<1,即0<An-Bn*sqrt(6)<1,故An+Bn*sqrt(6)的整数部分为(2*An)-1。
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<stdio.h>
using namespace std;
const long long M=1024;
struct data
{
long long mat[2][2];
} a;
int t,n;
data Times(data x,data y)
{
data z;
for (int i=0; i<2; i++)
for (int j=0; j<2; j++)
z.mat[i][j]=0;
for (int i=0; i<2; i++)
for (int j=0; j<2; j++)
for (int k=0; k<2; k++)
z.mat[i][j]=( z.mat[i][j]+ (x.mat[i][k]*y.mat[k][j])%M )%M;
return z;
}
data Fast_power(int x)
{
if (x==1) return a;
data mid=Fast_power(x/2);
data temp=Times(mid,mid);
if (x&1) temp=Times(temp,a);
return temp;
}
int main()
{
//freopen("hdu2256.in","r",stdin);
//freopen("hdu2256.out","w",stdout);
scanf("%d",&t);
for (int q=1; q<=t; q++)
{
scanf("%d",&n);
if (n==1)
{
printf("9\n");
continue;
}
a.mat[0][0]=5; a.mat[0][1]=12;
a.mat[1][0]=2; a.mat[1][1]=5;
data temp=Fast_power(n-1);
long long A=(temp.mat[0][0]*5LL)%M;
A=( A+ (temp.mat[0][1]*2LL)%M )%M;
A=(A*2LL)%M;
A=(A+M-1LL)%M;
printf("%I64d\n",A);
}
return 0;
}