2013长沙邀请赛A So Easy!(矩阵快速幂,共轭)

本文介绍如何使用矩阵快速幂技巧解决特定序列计算问题,包括输入解析、矩阵初始化、矩阵乘法、矩阵快速幂算法实现及输出结果,提供了解决类似问题的高效算法策略。

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

So Easy!

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


Problem Description
  A sequence Sn is defined as:

Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn.
  You, a top coder, say: So easy! 
 

Input
  There are several test cases, each test case in one line contains four positive integers: a, b, n, m. Where 0< a, m < 215, (a-1)2< b < a2, 0 < b, n < 231.The input will finish with the end of file.
 

Output
  For each the case, output an integer Sn.
 

Sample Input
2 3 1 2013 2 3 2 2013 2 2 1 2013
 

Sample Output
4 14 4
 
挑战程序设计竞赛P268,关键是求初始矩阵:
an+1 = a*an+b*bn;
bn+1 = an+a*bn;
a[0][0],a[0][1]分别是公式1里面的系数,a和b;
a[1][0],a[1][1]分别是公式2里面的系数,1和a;
然后就是矩阵快速幂了:
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<algorithm>
 6 #include<cmath>
 7 #define M(a,b) memset(a,b,sizeof(a))
 8 typedef long long LL;
 9 
10 using namespace std;
11 
12 
13 long long a,b,n,m;
14 
15 struct matrix
16 {
17     LL mat[2][2];
18     void init()
19     {
20         mat[0][0] = a;
21         mat[0][1] = b;
22         mat[1][0] = 1;
23         mat[1][1] = a;
24     }
25 };
26 
27 matrix mamul(matrix aa,matrix bb)
28 {
29     matrix c;
30     for(int i = 0;i<2;i++)
31     {
32         for(int j = 0;j<2;j++)
33         {
34             c.mat[i][j] = 0;
35             for(int k = 0;k<2;k++)
36                 c.mat[i][j]+=(aa.mat[i][k]*bb.mat[k][j]);
37             c.mat[i][j]%=m;
38         }
39     }
40     return c;
41 }
42 
43 matrix mul(matrix s, int k)
44 {
45     matrix ans;
46     ans.init();
47     while(k>=1)
48     {
49         if(k&1)
50             ans = mamul(ans,s);
51         k = k>>1;
52         s = mamul(s,s);
53     }
54     return ans;
55 }
56 
57 int main()
58 {
59     while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&n,&m)==4)
60     {
61             matrix ans;
62             ans.init();
63             ans = mul(ans,n-1);
64             printf("%I64d\n",(ans.mat[0][0]*2+m)%m);
65     }
66     return 0;
67 }

 

 

转载于:https://www.cnblogs.com/haohaooo/p/4019934.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值