zoukankan      html  css  js  c++  java
  • 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 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
     
    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 }
  • 相关阅读:
    用带缓冲区的文件流FileStream来实现大文件的拷贝
    委托与事件、匿名方法与Lambda表达式
    C#基础点记录
    C#基础知识06
    用while语句实现用户登陆程序
    TSQL检索电话呼叫员的工作流水信息
    委托
    类型转换、异常、String知识总结
    内网入库单管理系统
    用C#打印出正等腰三角形
  • 原文地址:https://www.cnblogs.com/chenhuan001/p/3350669.html
Copyright © 2011-2022 走看看