题意:
给定
n
n
n,问
(
1
+
2
)
n
(1+\sqrt 2)^n
(1+2)n能否分解成
m
+
m
−
1
\sqrt m + \sqrt {m-1}
m+m−1
如果可以 输出
m
%
(
1
e
9
+
7
)
m \% (1e9+7)
m%(1e9+7) 否则 输出
n
o
no
no。
思路:
假设等式成立,则:
(
1
+
2
)
n
=
m
+
m
−
1
(1+\sqrt 2)^n = \sqrt m + \sqrt {m-1}
(1+2)n=m+m−1
因为
2
\sqrt 2
2计算机不能精确表示,所以自然会想办法将其消去。
故等号两边同乘上
(
2
−
1
)
n
(\sqrt2 - 1)^n
(2−1)n,有:
1 = ( m + m − 1 ) ∗ ( 2 − 1 ) n 1 = (\sqrt m + \sqrt {m-1})*(\sqrt2 - 1)^n 1=(m+m−1)∗(2−1)n
由根号计算的性质,有:
(
2
−
1
)
n
=
m
−
m
−
1
(\sqrt2 - 1)^n = \sqrt m - \sqrt {m-1}
(2−1)n=m−m−1
当n = 1,显然有
2
−
1
\sqrt {2} - \sqrt {1}
2−1
当n = 2,显然有
9
−
8
\sqrt {9} - \sqrt {8}
9−8
当n = 3,显然有
50
−
49
\sqrt {50} - \sqrt {49}
50−49
当n = 4,显然有
289
−
288
\sqrt {289} - \sqrt {288}
289−288
…
注意
m
m
m组成的数列
a
a
a:2,9,50,289…
观察易发现:
a
[
i
]
=
6
∗
a
[
i
−
1
]
−
a
[
i
−
2
]
−
2
a[i] = 6*a[i-1] - a[i-2] - 2
a[i]=6∗a[i−1]−a[i−2]−2
故使用矩阵快速幂即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
class Matrix{
public:
ll a[5][5];
}ori,res;
void Init(){
memset(ori.a,0,sizeof(ori.a));memset(res.a,0,sizeof(res.a));
ori.a[1][1] = 6;ori.a[1][2] = -1;ori.a[1][3] = -2;
ori.a[2][1] = ori.a[3][3] = 1;
res.a[1][1] = res.a[2][2] = res.a[3][3] = 1;
}
void Mult(Matrix A,Matrix B,Matrix& C){
memset(C.a,0,sizeof(C.a));
for(int i=1 ;i<=3 ;i++){
for(int j=1 ;j<=3 ;j++){
for(int k=1 ;k<=3 ;k++){
C.a[i][j] = (C.a[i][j] + A.a[i][k]*B.a[k][j]%mod)%mod;
}
}
}
}
void fast_mod(ll m){
while(m){
if(m&1) Mult(res,ori,res); //a*b = c
Mult(ori,ori,ori);
m >>= 1;
}
}
int main(){
Init();
ll n;
scanf("%I64d",&n);
if(n == 0) puts("1");
else if(n == 1) puts("2");
else if(n == 2) puts("9");
else{
fast_mod(n-2);
ll ans = (1LL*res.a[1][1]*9%mod + 1LL*res.a[1][2]*2%mod + 1LL*res.a[1][3]%mod)%mod;
if(ans<0) ans+=mod;
printf("%I64d\n",ans);
}
return 0;
}