hdu4565(矩阵快速幂+经典的数学处理)

注意题目的一个关键条件(a-1)2< b < a2 , 于是可以知道    0 < a-√b < 1 ,所以 (a-√b)^n < 1 . 然后 (a+ √b)^n+(a-√b)^n 的值为整数且正好是 (a+√b)^n的向上取整.

然后就可以得到递推式 f[n+1]=2*a*f[n]-(a*a-b)*f[n-1] . 

然后构造矩阵。 幂乘即可. 

 

                So Easy!

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


Problem Description
  A sequence S n 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 S n.
  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 < 2 15, (a-1) 2< b < a 2, 0 < b, n < 2 31.The input will finish with the end of file.
 

 

Output
  For each the case, output an integer S n.
 

 

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

 

Sample Output
4 14 4
 

 

Source
 

 

Recommend
zhoujiaqi2010
 

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <algorithm>
 5 #include <math.h>
 6 #include <map>
 7 #include <queue>
 8 #include <sstream>
 9 #include <iostream>
10 using namespace std;
11 #define INF 0x3fffffff
12 
13 typedef __int64 LL;
14 
15 LL a,b,n,m;
16 LL g[2][2];
17 LL MOD;
18 
19 void cal(LL s[2][2],LL t[2][2])
20 {
21     LL tmp[2][2];
22     memset(tmp,0,sizeof(tmp));
23     for(int k=0;k<2;k++)
24         for(int i=0;i<2;i++)
25             for(int j=0;j<2;j++)
26             {
27                 tmp[i][j]=(tmp[i][j]+s[i][k]*t[k][j])%MOD;
28             }
29     for(int i=0;i<2;i++)
30         for(int j=0;j<2;j++)
31             s[i][j]=tmp[i][j];
32 }
33 
34 
35 int main()
36 {
37     //freopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);
38     //freopen("C:\\Users\\Administrator\\Desktop\\in.txt","w",stdout);
39     while(scanf("%d%d%d%d",&a,&b,&n,&m)!=EOF)
40     {
41         MOD=m;
42         g[0][0]=2*a; g[0][1]=1;
43         g[1][0]=b-a*a; g[1][1]=0;
44 
45         n--;
46         LL sum[2][2];
47         for(int i=0;i<2;i++)
48             for(int j=0;j<2;j++)
49                 if(i==j) sum[i][j]=1;
50                 else sum[i][j]=0;
51         while(n)
52         {
53             if( (n&1)!=0)
54                 cal(sum,g);
55             cal(g,g);
56             n>>=1;
57         }
58         LL ans=((2*a*sum[0][0]+2*sum[1][0])%MOD+MOD)%MOD;
59         cout<<ans<<endl;
60     }
61     return 0;
62 }

 

 

转载于:https://www.cnblogs.com/chenhuan001/p/3350669.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值