HDU 4291 A Short problem

本文介绍了一种利用矩阵快速幂解决特定递推数列问题的方法,并提供了完整的C++代码实现。通过具体示例,展示了如何高效计算g(g(g(n))) mod 10^9 +7,其中g(n)为特定的递推公式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A Short problem

Time Limit: 1000ms
Memory Limit: 32768KB
This problem will be judged on  HDU. Original ID: 4291
64-bit integer IO format: %I64d      Java class name: Main
 
 According to a research, VIM users tend to have shorter fingers, compared with Emacs users.
  Hence they prefer problems short, too. Here is a short one:
  Given $n (1 \leq n \leq 10^{18})$, You should solve for 
\[g(g(g(n))) mod 10^9 + 7\]

  where
\[g(n) = 3g(n - 1) + g(n - 2)\]

\[g(1) = 1\]

\[g(0) = 0\]

 

Input

  There are several test cases. For each test case there is an integer n in a single line.
  Please process until EOF (End Of File).
 

Output

  For each test case, please print a single line with a integer, the corresponding answer to this case.
 

Sample Input

0
1
2

Sample Output

0
1
42837

Source

 
解题:矩阵快速幂,关键在于如何找到内部循环的的模对象
 
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int maxn = 3;
 5 LL mod = 1000000007;
 6 const int n = 2;
 7 struct Matrix {
 8     LL m[maxn][maxn];
 9     void init() {
10         memset(m,0,sizeof m);
11     }
12     Matrix() {
13         init();
14     }
15     Matrix operator*(const Matrix &rhs) const {
16         Matrix ret;
17         for(int k = 0; k < n; ++k) {
18             for(int i = 0; i < n; ++i)
19                 for(int j = 0; j < n; ++j)
20                     ret.m[i][j] = (ret.m[i][j] + m[i][k]*rhs.m[k][j]%mod)%mod;
21 
22         }
23         return ret;
24     }
25     void set_a() {
26         init();
27         m[0][0] = 0;
28         m[0][1] = 1;
29     }
30     void set_b() {
31         init();
32         m[0][0] = 0;
33         m[0][1] = m[1][0] = 1;
34         m[1][1] = 3;
35     }
36     void print() {
37         for(int i = 0; i < n; ++i) {
38             for(int j = 0; j < n; ++j)
39                 cout<<m[i][j]<<" ";
40             cout<<endl;
41         }
42     }
43 };
44 Matrix a,b;
45 LL quickPow(LL index,LL md) {
46     a.set_a();
47     b.set_b();
48     mod = md;
49     while(index) {
50         if(index&1) {
51             a = a*b;
52         }
53         index >>= 1;
54         b = b*b;
55     }
56     return a.m[0][0];
57 }
58 int main() {
59     LL m;
60     while(~scanf("%I64d",&m))
61         printf("%I64d\n",quickPow(quickPow(quickPow(m,183120),222222224),1000000007));
62     return 0;
63 }
View Code

 

转载于:https://www.cnblogs.com/crackpotisback/p/4816245.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值