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 ", m); 39 } 40 return 0; 41 }