hdu-2256 Problem of Precision---矩阵快速幂+数学技巧
Posted fzl194
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu-2256 Problem of Precision---矩阵快速幂+数学技巧相关的知识,希望对你有一定的参考价值。
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2256
题目大意:
题目要求的是(sqrt(2)+sqrt(3))^2n %1024向下取整的值
解题思路:
这里很多人会直接认为结果等于(an+bn*sqrt(6))%1024,但是这种结果是错的,因为这边涉及到了double,必然会有误差,所以根double有关的取模都是错误的思路
转载于:https://blog.csdn.net/chenguolinblog/article/details/10212567
上述思路是转载的,我就是上面说的“很多人”,虽然递推矩阵写出来的,但是还是没想到可以转化成上面那样。直接输出2*a-1就是答案。这里也需要记住double取模是错误的
1 #include<bits/stdc++.h> 2 using namespace std; 3 int MOD = 1024; 4 struct Mat 5 { 6 int a[4][4]; 7 int n, m;//n为行数,m为列数 8 Mat(int n, int m):n(n), m(m) 9 { 10 memset(a, 0, sizeof(a)); 11 } 12 void init() 13 { 14 for(int i = 0; i < n; i++)a[i][i] = 1;//初始化成单位矩阵 15 } 16 void output() 17 { 18 for(int i = 0; i < n; i++) 19 { 20 for(int j = 0; j < m; j++) 21 { 22 cout<<a[i][j]<<" "; 23 } 24 cout<<endl; 25 } 26 } 27 }; 28 Mat mul(Mat a, Mat b)//矩阵乘法 29 { 30 Mat tmp(a.n, b.m);//矩阵乘法结果矩阵行数为a的行数,列数为b的列数 31 for(int i = 0; i < a.n; i++) 32 { 33 for(int j = 0; j < b.m; j++) 34 { 35 for(int k = 0; k < a.m; k++)//a.m == b.n(乘法的前提条件) 36 { 37 tmp.a[i][j] += (a.a[i][k] * b.a[k][j] % MOD); 38 tmp.a[i][j] %= MOD; 39 } 40 } 41 } 42 return tmp; 43 } 44 Mat pow(Mat a, int n) 45 { 46 Mat tmp(a.n, a.m); 47 tmp.init(); 48 while(n) 49 { 50 if(n & 1)tmp = mul(tmp, a); 51 n /= 2; 52 a = mul(a, a); 53 } 54 return tmp; 55 } 56 int main() 57 { 58 int T, n; 59 cin >> T; 60 Mat a(2, 2); 61 a.a[0][0] = 5, a.a[0][1] = 12; 62 a.a[1][0] = 2, a.a[1][1] = 5; 63 while(T--) 64 { 65 cin >> n; 66 Mat ans = pow(a, n); 67 //ans.output(); 68 int x = ans.a[0][0], y = ans.a[1][0]; 69 cout<<(2 * x - 1) % MOD<<endl; 70 } 71 }
以上是关于hdu-2256 Problem of Precision---矩阵快速幂+数学技巧的主要内容,如果未能解决你的问题,请参考以下文章
HDU2256-Problem of Precision(矩阵构造+高速幂)
hdu-2256 Problem of Precision---矩阵快速幂+数学技巧
HDU 2256 Problem of Precision 数论矩阵快速幂