51nod 1537 分解

1537 分解

基准时间限制:0.5 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 
 问(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 + √2)*(a + b√2) = (a+2b) + (a+b)√2

[a+2b] = [1 2] *[a]
[a+ b] [1 1] [b]
最后要判别一下n为奇数和偶数的情况
 1 #include <cstdio>
 2 #include <iostream>
 3 #include <cstring>
 4 const int mod = 1e9+7;
 5 using namespace std;
 6 struct mat {
 7     long long int  a[3][3];
 8     mat() {
 9         memset(a, 0, sizeof(a));
10     }
11     mat operator *(const mat &o) const {
12         mat t;
13         for(int i = 1; i <= 2; i++) {
14             for(int j = 1; j <= 2; j++)
15                 for(int k = 1; k <= 2; k++) {
16                     t.a[i][j] = (t.a[i][j] + a[i][k]*o.a[k][j]%mod)%mod;
17                 }
18         }
19         return t;
20     }
21 } a, b;
22 
23 int main() {
24     long long n, tmp;
25     while(~scanf("%I64d", &n)) {
26         tmp = n;
27         a.a[1][1] = a.a[2][2] = 1, a.a[1][2] = a.a[2][1] = 0;
28         b.a[1][1] = b.a[2][1] = b.a[2][2] = 1, b.a[1][2] = 2;
29             while(n > 0) {
30                 if(n&1) {
31                     a = b*a;
32                     n--;
33                 }
34                 n >>= 1;
35                 b = b*b;
36             }
37            long long int m = (a.a[1][1]*a.a[1][1] + (tmp%2)) %mod;
38            printf("%I64d\n", m);
39     }
40     return 0;
41 }

 

 

posted on 2016-09-28 22:38  disppr  阅读(317)  评论(0编辑  收藏  举报