HDU 4565 So Easy! (矩阵快速幂 + 向上取整)

来源:互联网 发布:python 量化交易策略 编辑:程序博客网 时间:2024/06/05 15:30

So Easy!

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


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 20132 3 2 20132 2 1 2013
 

Sample Output
4144
 

Source
2013 ACM-ICPC长沙赛区全国邀请赛——题目重现
 


这个题 与 HUD 2256 的套路 一模一样,  2256 是向下取整, 这个是向上 取整,  但是整体思路一致 

HUD 2256 题解链接: http://blog.csdn.net/sizaif/article/details/77112848

构造的矩阵为  [a,b]        

        [1,a]

ans = 2*An     An= a*X0 + b* Y0    又  X0=a,Y0=1;

所以 An = array[0][0]*a +array[0][1]


代码:

#include <iostream>#include <algorithm>#include <queue>#include <stdio.h>#include <cstring>#include <cmath>typedef long long ll;const int MAXN=2;const int N=10;using namespace std;int MOD;int a,b;struct Matrix{ll arr[N][N];void init(){memset(arr,0,sizeof(arr));for(int i=0;i<MAXN;i++)arr[i][i]=1;//初始化}void iinit(){memset(arr,0,sizeof(arr));arr[0][0]=arr[1][1]=a;arr[0][1]=b;arr[1][0]=1;}}A;Matrix mul(Matrix X,Matrix Y)// 矩阵乘法{Matrix ans;for(int i=0;i<MAXN;i++)for(int j=0;j<MAXN;j++){ans.arr[i][j]=0;for(int k=0;k<MAXN;k++){ans.arr[i][j]+=X.arr[i][k]*Y.arr[k][j];ans.arr[i][j]%=MOD;}}return ans;}Matrix Q_pow(Matrix B,int n)// 矩阵快速幂{Matrix ans;ans.init();while(n){if(n&1)ans=mul(ans,B);n>>=1;B=mul(B,B);}return ans;}int main(){    int n;    while(~scanf("%d %d %d %d",&a,&b,&n,&MOD))    {        Matrix ans;        if(n<=1)        {            printf("%d\n",(a+1+(int)sqrt(b))%MOD);            continue;        }            ans.iinit();            ans=Q_pow(ans,n-1);            ll res=0;           // cout<<ans.arr[0][0]<<" "<<ans.arr[0][1]<<endl;            res=(ans.arr[0][0]*a+ans.arr[0][1])%MOD;            printf("%lld\n",(2*(res))%MOD);    }    return 0;}


原创粉丝点击