HDU4990 Reading comprehension —— 递推、矩阵快速幂

题目链接:https://vjudge.net/problem/HDU-4990

 

Reading comprehension

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2329    Accepted Submission(s): 954


Problem Description
Read the program below carefully then answer the question.
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include<iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include<vector>

const int MAX=100000*2;
const int INF=1e9;

int main()
{
  int n,m,ans,i;
  while(scanf("%d%d",&n,&m)!=EOF)
  {
    ans=0;
    for(i=1;i<=n;i++)
    {
      if(i&1)ans=(ans*2+1)%m;
      else ans=ans*2%m;
    }
    printf("%d\n",ans);
  }
  return 0;
}
 

 

Input
Multi test cases,each line will contain two integers n and m. Process to end of file.
[Technical Specification]
1<=n, m <= 1000000000
 

 

Output
For each case,output an integer,represents the output of above program.
 

 

Sample Input
1 10 3 100
 

 

Sample Output
1 5
 

 

Source
 

 

Recommend
heyang

 

 

题解:

当n为奇数时,f[n] = 2*f[n-1]+1,f[n-1] = 2*f[n-2],所以:f[n] = f[n-1] + 2*f[n-2] + 1;

当n为偶数时,f[n] = 2*f[n-1],f[n-1] = 2*f[n-2] + 1,所以:f[n] = f[n-1] + 2*f[n-2] + 1;

综上:f[n] = f[n-1] + 2*f[n-2] + 1,构造矩阵:

 

 

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <cmath>
 7 #include <queue>
 8 #include <stack>
 9 #include <map>
10 #include <string>
11 #include <set>
12 using namespace std;
13 typedef long long LL;
14 const int INF = 2e9;
15 const LL LNF = 9e18;
16 //const int MOD = 10000007;
17 const int MAXN = 1e6+100;
18 
19 LL MOD;
20 const int Size = 3;
21 struct MA
22 {
23     LL mat[Size][Size];
24     void init()
25     {
26         for(int i = 0; i<Size; i++)
27         for(int j = 0; j<Size; j++)
28             mat[i][j] = (i==j);
29     }
30 };
31 
32 MA mul(MA x, MA y)
33 {
34     MA ret;
35     memset(ret.mat, 0, sizeof(ret.mat));
36     for(int i = 0; i<Size; i++)
37     for(int j = 0; j<Size; j++)
38     for(int k = 0; k<Size; k++)
39         ret.mat[i][j] += (1LL*x.mat[i][k]*y.mat[k][j])%MOD, ret.mat[i][j] %= MOD;
40     return ret;
41 }
42 
43 MA qpow(MA x, LL y)
44 {
45     MA s;
46     s.init();
47     while(y)
48     {
49         if(y&1) s = mul(s, x);
50         x = mul(x, x);
51         y >>= 1;
52     }
53     return s;
54 }
55 
56 MA tmp = {
57     1, 2, 1,
58     1, 0, 0,
59     0, 0, 1
60 };
61 
62 int main()
63 {
64     LL n, m;
65     while(scanf("%lld%lld",&n,&m)!=EOF)
66     {
67         MOD = m;
68         if(n<=2)
69         {
70             printf("%lld\n", n%MOD);
71             continue;
72         }
73 
74         MA s = tmp;
75         s = qpow(s, n-2);
76 
77         LL ans = ((2LL*s.mat[0][0]%MOD + s.mat[0][1])%MOD+s.mat[0][2])%MOD;
78         printf("%lld\n", ans);
79     }
80 }
View Code

 

posted on 2018-02-04 16:34  h_z_cong  阅读(249)  评论(0编辑  收藏  举报

导航