#include<iostream>
#include<string.h>
#include<algorithm>
#define N 1024
using namespace std;
typedef long long L;
typedef struct str
{ L s[2][2];//注意数据范围
}Node;
Node a,b;
Node ceil(Node p,Node q)
{ Node c;
memset(c.s,0,sizeof(c.s));
for(int i=0;i<2;++i)
for(int j=0;j<2;++j)
for(int t=0;t<2;++t)
c.s[i][j]=(c.s[i][j]+p.s[i][t]*q.s[t][j])%N;
return c;
}
Node doit(int k)
{ Node p=a,q=b;
while(k)
{ if(1&k) p=ceil(p,q);
q=ceil(q,q);
k=k>>1;
}
return p;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{ a.s[0][0]=a.s[1][1]=1;
a.s[0][1]=a.s[1][0]=0;
b.s[0][0]=b.s[1][1]=5;
b.s[0][1]=12;b.s[1][0]=2;
int n;
scanf("%d",&n);
if(n==1)
{ printf("9\n");
continue;
}
n--;
Node c=doit(n);
int sum=(5*c.s[0][0]+2*c.s[0][1])%N;
printf("%d\n",(2*sum-1)%N);//注意结果是对1024取余
}return 0;
}
/*
思路:构造矩阵,然后进行矩阵二分幂运算。
构造过程:
(sqrt(2)+sqrt(3))^2=5+2*sqrt(6);
(5+2*sqrt(6))^n=An+Bn*sqrt(6);
Bn*sqrt(6)=An-(5-2*sqrt(6))^n;//因为此项等于(0.101...)^n 约等于0
(5+2*sqrt(6))^n=2*An-Bn*sqrt(6);
An+Bn*sqrt(6)=(A(n-1)+B(n-1)*sqrt(6))*(5+2*sqrt(6))=(5*A(n-1)+12B(n-1))+(5*B(n-1)+2*A(n-1))*sqrt(6)
所以有:
An=5*A(n-1)+12B(n-1)
Bn=2*A(n-1)+5*B(n-1)
(5+2*sqrt(6))^n=An+Bn*sqrt(6)+(5-2*sqrt(6))^n=An-Bn*sqrt(6)=2An-(0.101...)^n
所以(5+2*sqrt(6))^n=2An-1
最后的答案ans=2An-1;
而矩阵为
| 5 12|
| 2 5|
*/
http://acm.hdu.edu.cn/showproblem.php?pid=2256&&构造矩阵求值
最新推荐文章于 2018-04-03 19:47:11 发布