题目
http://acm.hdu.edu.cn/showproblem.php?pid=2256
-
Problem Description
-
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 <= 109) -
Output
For each input case, you should output the answer in one line. -
Sample Input
3
1
2
5 -
Sample Output
9
97
841
题意
计算如图所示的式子
思路
推到答案和n的关系
原
式
(
2
+
3
)
2
n
=
(
5
+
2
6
)
n
.
原式(\sqrt{2}+\sqrt{3})^{2n} = (5+2\sqrt{6})n.
原式(2+3)2n=(5+26)n.
令
(
5
+
2
6
)
n
=
A
n
+
B
n
6
.
令(5+2\sqrt{6})^n = A_n +B_n\sqrt{6}.
令(5+26)n=An+Bn6.
A
n
+
B
n
6
=
(
5
+
2
6
)
(
A
n
−
1
+
B
n
−
1
6
)
A_n +B_n\sqrt{6} = (5+2\sqrt{6})(A_{n-1} +B_{n-1}\sqrt{6})
An+Bn6=(5+26)(An−1+Bn−16)
=
(
5
A
n
−
1
+
12
B
n
−
1
)
+
(
2
A
n
−
1
+
5
B
n
−
1
)
∗
6
.
= (5A_{n-1}+12B_{n-1})+(2A_{n-1}+5B_{n-1})*\sqrt{6}.
=(5An−1+12Bn−1)+(2An−1+5Bn−1)∗6.
对
应
A
n
=
5
A
n
−
1
+
12
B
n
−
1
对应A_n=5A_{n-1}+12B_{n-1}
对应An=5An−1+12Bn−1
B
n
=
(
2
A
n
−
1
+
5
B
n
−
1
)
∗
6
B_n=(2A_{n-1}+5B_{n-1})*\sqrt{6}
Bn=(2An−1+5Bn−1)∗6
然后是Xn,Yn和答案的关系:
(
5
−
2
6
)
n
=
A
n
−
B
n
6
<
1
(5-2\sqrt{6})^n = A_n -B_n\sqrt{6} < 1
(5−26)n=An−Bn6<1
a
n
s
=
A
n
+
B
n
6
+
(
A
n
−
B
n
6
)
−
(
A
n
−
B
n
6
)
ans = A_n +B_n\sqrt{6} + (A_n-B_n\sqrt{6}) - (A_n -B_n\sqrt{6})
ans=An+Bn6+(An−Bn6)−(An−Bn6)
=
2
A
n
−
(
A
n
−
B
n
6
)
=2A_n - (A_n -B_n\sqrt{6})
=2An−(An−Bn6)
2
A
n
−
(
A
n
−
B
n
6
)
取
整
为
2
A
n
−
1
2A_n - (A_n -B_n\sqrt{6}) 取整为 2A_n - 1
2An−(An−Bn6)取整为2An−1
即
a
n
s
=
2
A
n
−
1
即ans = 2A_n - 1
即ans=2An−1
矩阵快速幂
和快速幂唯一的区别是 整数 相乘变成了 矩阵相乘
代码
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int MOD = 1024;
struct matrix {
ll m[3][3];
matrix friend operator *(matrix a,matrix b) {
matrix c;
for(int i=1; i<=2; i++)
for(int j=1; j<=2; j++)
c.m[i][j]=0;
for(int i=1; i<=2; i++)
for(int j=1; j<=2; j++)
for(int k=1; k<=2; k++)
c.m[i][j] = (c.m[i][j]+a.m[i][k]*b.m[k][j])%MOD;
return c;
}
} Rematrix,ansmatrix;
matrix m_pow(matrix a,int b) {
matrix ans;
ans.m[1][1]=ans.m[2][2]=1;
ans.m[1][2]=ans.m[2][1]=0;
while(b) {
if(b & 1)
ans=ans*a;
a=a*a;
b>>=1;
}
return ans;
}
int main() {
int N;
scanf("%d",&N);
int n;
Rematrix.m[1][1]=5;
Rematrix.m[1][2]=12;
Rematrix.m[2][1]=2;
Rematrix.m[2][2]=5;
long long ans=0;
for(int i=1; i<=N; ++i) {
scanf("%d",&n);
ansmatrix = m_pow(Rematrix,n-1);
ans = (5*ansmatrix.m[1][1] + 2*ansmatrix.m[1][2])%MOD ;
printf("%lld\n",(2*ans-1+MOD)%MOD);
}
return 0;
}