题意:
给出n,求((sqrt(2)+sqrt(3))^(2*n))%1024
解题思路:
(sqrt(2)+sqrt(3))^2 = (5+2*sqrt(6))
(5+2*sqrt(6))^n = Xn+Yn*sqrt( 6 ) = ( Xn-1+Yn-1*sqrt( 6 ) ) * ( 5+2*sqrt( 6 ) )
= (5*Xn-1+12*Yn-1) + (2*Xn-1+5*Yn-1)*sqrt( 6 )
所以Xn = 5*Xn-1+12*Yn-1 Yn = 2*Xn-1+5*Yn-1
矩阵就容易构造了
结果需要处理一下,不能直接算
(5-2*sqrt(6))^n = (0,101)^n 近似为0
Xn+Yn*sqrt( 6 ) = Xn+Yn-1+Xn-Yn-1-(Xn-Yn*sqrt( 6 )) = 2*Xn-(0.101..)^n
向下取整
所以最终结果是2*Xn-1
错误点:
直接认为结果等于(an+bn*sqrt(6))%1024,但是这种结果是错的,因为这边涉及到了double,必然会有误差,所以根double有关的取模都是错误的思路
#include <iostream>
#include <string>
#include <cstring>
#include <cstdio>
#include <math.h>
#include <algorithm>
using namespace std;
#define mod 1024
struct matrix
{
int a[2][2];
};
matrix mul(matrix a,matrix b)
{
matrix ret;
memset(ret.a,0,sizeof(ret.a));
for(int i = 0;i<2;i++)
{
for(int j=0;j<2;j++)
{
ret.a[i][j] = (a.a[i][0]*b.a[0][j]+a.a[i][1]*b.a[1][j])%mod;
}
}
return ret;
}
matrix mpower(matrix a,__int64 x)
{
matrix I;
I.a[0][0] = I.a[1][1] = 1;
I.a[0][1] = I.a[1][0] = 0;
while(x)
{
if(x&1) I = mul(I,a);
x>>=1;
a = mul(a,a);
}
return I;
}
int main()
{
int t;
cin>>t;
while(t--)
{
matrix tmp;
tmp.a[0][0] = 5;
tmp.a[0][1] = 12;
tmp.a[1][0] = 2;
tmp.a[1][1] = 5;
__int64 n;
cin>>n;
tmp = mpower(tmp,n-1);
int x,y;
x = (tmp.a[0][0]*5+tmp.a[0][1]*2)%mod;
y = (tmp.a[1][0]*5+tmp.a[1][1]*2)%mod;
int sum = (2*x-1+mod)%mod;
cout<<sum<<endl;
}
return 0;
}