转载地址:http://blog.csdn.net/chenguolinblog/article/details/10212567
思路: 矩阵快速幂
分析:
1 题目要求的是(sqrt(2)+sqrt(3))^2n %1024向下取整的值
3 这里很多人会直接认为结果等于(an+bn*sqrt(6))%1024,但是这种结果是错的,因为这边涉及到了double,必然会有误差,所以根double有关的取模都是错误的思路
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int MOD = 1024;
const int N = 2;
struct Matrix{
int mat[N][N];
Matrix operator*(const Matrix& m)const{
Matrix tmp;
for(int i = 0 ; i < N ; i++){
for(int j = 0 ; j < N ; j++){
tmp.mat[i][j] = 0;
for(int k = 0 ; k < N ; k++){
tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD;
tmp.mat[i][j] %= MOD;
}
}
}
return tmp;
}
};
int Pow(Matrix &m , int k){
if(k == 1)
return 9;
k--;
Matrix ans;
memset(ans.mat , 0 , sizeof(ans.mat));
for(int i = 0 ; i < N ; i++)
ans.mat[i][i] = 1;
while(k){
if(k&1)
ans = ans*m;
k >>= 1;
m = m*m;
}
int x = (ans.mat[0][0]*5+ans.mat[0][1]*2)%MOD;
return (2*x-1)%MOD;
}
int main(){
int cas , n;
Matrix m;
scanf("%d" , &cas);
while(cas--){
scanf("%d" , &n);
m.mat[0][0] = 5 ; m.mat[1][1] = 5;
m.mat[1][0] = 2 ; m.mat[0][1] = 12;
printf("%d\n" , Pow(m , n));
}
}
下边是自己的代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int mod=1024;
int n;
struct mat
{
long long mm[2][2];
};
mat operator*(mat a,mat b)
{
mat c;
memset(c.mm,0,sizeof(c.mm));
for(int i=0; i<2; i++)
for(int j=0; j<2; j++)
for(int k=0; k<2; k++)
{
c.mm[i][j]+=a.mm[i][k]*b.mm[k][j];
c.mm[i][j]%=mod;
}
return c;
}
void pow(int n)
{
if(n==1)
printf("9\n");
else
{
n--;
mat res,ans;
memset(ans.mm,0,sizeof(ans.mm));
for(int i=0; i<2; i++)
ans.mm[i][i]=1;
res.mm[0][0]=5;
res.mm[0][1]=2;
res.mm[1][0]=12;
res.mm[1][1]=5;
while(n)
{
if(n%2==1)
ans=ans*res;
res=res*res;
n/=2;
}
int x=(ans.mm[0][0]*5+ans.mm[0][1]*12)%mod;
printf("%d\n",(2*x-1)%mod);
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
pow(n);
}
}