问(1+sqrt(2)) ^n 能否分解成 sqrt(m) +sqrt(m-1)的形式
如果可以 输出 m%1e9+7 否则 输出no
Input
一行,一个数n。(n<=10^18)
Output
一行,如果不存在m输出no,否则输出m%1e9+7
Input示例
2
Output示例
9
可以构造出:
假设(1-sqrt(2))N-1次为:A+B*sqrt2
则(1-sqrt(2))N次为:A+2*B +(A+B)*sqrt2
类斐波那契---
矩阵| 1 2|
|1 1 |
最后结果为sqrt(m)+sqrt(m-1)
要对m取模---
所以--A+B*sqrt2===sqrt(A*A)+sqrt(2*B*B)
当某一步为(A+10^9+7)+B*sqrt2时---
下一步为(A+10^9+7+2*B)+(B+A+10^9+7)*sqrt2--
等价于取模后---A+B*sqrt2----的
下一步为:(A+2*B)+(B+A)*sqrt2
即对A和B取模不会影响最后的结果。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
LL mod=1000000007;
struct node{
LL shu[2][2];
void clear()
{
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
shu[i][j]=0;
}
node operator * (const node &B) const{
node C;
C.clear();
for (int i=0;i<2;i++)
for (int j=0;j<2;j++)
for (int k=0;k<2;k++)
C.shu[i][j]=(C.shu[i][j]+shu[i][k]*B.shu[k][j])%mod;
return C;
}
}A,B;
int main()
{
LL n;
scanf("%lld",&n);
if (n==0)
{
printf("1\n");
return 0;
}
LL nn=n;
A.clear();
for (int i=0;i<2;i++)
A.shu[i][i]=1;
for (int i=0;i<2;i++)
B.shu[i][i]=1;
B.shu[0][1]=2;B.shu[1][0]=1;
nn--;
while (nn)
{
if (nn&1)
A=A*B;
B=B*B;
nn/=2;
}
LL a=(A.shu[0][0]+A.shu[0][1])%mod;
LL b=(A.shu[1][0]+A.shu[1][1])%mod;
if (n%2==0)
{
a=(a*a)%mod;
printf("%lld\n",a);
}
else
{
b=(b*b*2)%mod;
printf("%lld\n",b);
}
return 0;
}