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 }

 

posted @ 2018-04-18 22:27  _努力努力再努力x  阅读(157)  评论(0编辑  收藏  举报