hdu4565矩阵快速幂

 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
#include <cstdio>
#include <cstring>
#include <iostream>
#include<cmath>
#define ll long long
using namespace std;
ll n,m;
ll a,b;
struct matrix
{
    ll mat[15][15];
    matrix()
    {
        memset(mat,0,sizeof(mat));
    }
};
matrix mul(matrix B,matrix A)
{
    int i,j,k;
    matrix C;
    for(i=1;i<=2;i++)
        for(j=1;j<=2;j++)
        for(k=1;k<=2;k++)
        C.mat[i][j]=(C.mat[i][j]+B.mat[i][k]*A.mat[k][j])%m;
    return C;

}
matrix pow(matrix A,ll p)
{
    matrix ans;
    for(int i=1;i<=2;i++)
        ans.mat[i][i]=1;
    while(p)
    {
        if(p&1)
            ans=mul(ans,A);
        A=mul(A,A);
        p>>=1;
    }
    return ans;
}
int main()
{
    while(~scanf("%lld%lld%lld%lld",&a,&b,&n,&m))
    {
        matrix A,B;

        A.mat[1][1]=a%m;
        A.mat[1][2]=b%m;
        A.mat[2][1]=1;
        A.mat[2][2]=a%m;
        B.mat[1][1]=a%m;
        B.mat[2][1]=1;
        A=pow(A,n-1);
        A=mul(A,B);
        printf("%lld\n",2*A.mat[1][1]%m);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/sdauguanweihong/article/details/90063856