Problem of Precision
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1043 Accepted Submission(s): 612
Problem Description
![](https://i-blog.csdnimg.cn/blog_migrate/452366445ca2fdd383e1e9275ee65a60.jpeg)
Input
The first line of input gives the number of cases, T. T test cases follow, each on a separate line. Each test case contains one positive integer n. (1 <= n <= 10^9)
Output
For each input case, you should output the answer in one line.
Sample Input
3 1 2 5
Sample Output
9 97 841
Source
注:(
√2+√3)^2n = ((√2+√3)^2)^n = (5+2√6)^n
由于√6消除不掉,设(5+2√6)^n = an+bn√6
则第n+1项 a(n+1) + b(n+1)√6 = (5+2√6)*(an + bn√6) = (5an+12bn) + (2an+5bn)√6
即a(n+1) = 5an+12bn,,b(n+1) = 2an+5bn
可由此构建矩阵
| 5 12 | *| an | = | a(n+1) |
| 2 5 | | bn | | b(n+1) |
再 (5+2√6)^n 向下取整 首先double不可取余操作
故令 (5+2√6)^n + (5-2√6)^n = (an+bn√6) + (an-bn√6) = 2an
又(5-2√6) ≈ 0.101020... (5-2√6)^n 无限趋近于 0
所以(5+2√6)^n 向下取整 即为 2an-1
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct node{
int m[2][2];
}res,per;
int t,n;
const int m = 1024;
void init(){
per.m[0][0] = per.m[1][1] = 1;
per.m[0][1] = per.m[1][0] = 0;
res.m[0][0] = res.m[1][1] = 5;
res.m[0][1] = 12;
res.m[1][0] = 2;
}
node mutil(node a,node b){
int i,j,k;
node c;
for( i = 0 ; i< 2 ; ++i )
for( j = 0 ; j < 2 ; ++j ){
c.m[i][j] = 0;
for( k = 0 ; k < 2 ; ++k )
c.m[i][j] += (a.m[i][k] * b.m[k][j])%m;
c.m[i][j] %= m;
}
return c;
}
void modefy( int k ){
node ans = per,p = res;
while( k ){
if( k&1 ) ans = mutil(ans,p);
p = mutil(p,p);
k>>=1;
}
// for( int i = 0 ; i < 2 ; ++i )
// printf("---- %d %d\n",ans.m[i][0],ans.m[i][1]);
printf("%d\n",(10*ans.m[0][0] + 4*ans.m[0][1] - 1) % m);
}
int main(){
init();
scanf("%d",&t);
while(t--){
scanf("%d",&n);
if( n == 1 )
printf("9\n");
else modefy(n-1);
}
return 0;
}