hdu 4565 - So Easy!(矩阵快速幂)

典型的矩阵快速幂:http://blog.csdn.net/coraline_m/article/details/9977405

代码如下:

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <set>
#include <map>

#define M 1005
#define INF 0x7fffffff
#define eps 1e-8
#define LL long long

using namespace std;

LL a, b, n, m, ret[2][2], A[2][2];

void init()
{
    ret[0][0] = 2*a;
    ret[0][1] = -(a*a-b);
    ret[1][0] = 1;
    ret[1][1] = 0;
    A[0][0] = 2*a;
    A[0][1] = -(a*a-b);
    A[1][0] = 1;
    A[1][1] = 0;
}
void cal(LL a[][2], LL b[][2], LL c[][2])
{
    LL temp[2][2];
    memset(temp, 0, sizeof(temp));
    for(int i = 0; i < 2; ++i)
        for(int j = 0; j < 2; ++j)
            for(int l = 0; l < 2; ++l)
                temp[i][j] += a[i][l]*b[l][j], temp[i][j]%=m;
    for(int i = 0; i < 2; ++i)
        for(int j = 0; j < 2; ++j)
            c[i][j] = temp[i][j];
}
int main()
{
    while(~scanf("%I64d%I64d%I64d%I64d", &a, &b, &n, &m))
    {
        LL ans;
        init();
        if(n>1)
        {
            n -= 2;
            while(n)
            {
                if(n&1)
                    cal(ret, A, ret);
                n >>= 1;
                cal(A, A, A);
            }
            ans = ((ret[0][0]*2*a+ret[0][1]*2)%m+m)%m;
        }
        else ans = 2*a%m;

        printf("%I64d\n", ans);
    }
    return 0;
}


你可能感兴趣的:(hdu 4565 - So Easy!(矩阵快速幂))