Guessing the Dice Roll HDU - 5955 (矩阵快速幂+推导)

Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers a and b on a blackboard. And then, the cows would say their identity number one by one. The first cow says the first number a and the second says the second number b. After that, the i-th cow says the sum of twice the (i-2)-th number, the (i-1)-th number, and i4i4. Now, you need to write a program to calculate the number of the N-th cow in order to check if John’s cows can make it right.
Input
The first line of input contains an integer t, the number of test cases. t test cases follow.
Each case contains only one line with three numbers N, a and b where N,a,b < 2^31 as described above.
Output
For each test case, output the number of the N-th cow. This number might be very large, so you need to output it modulo 2147493647.
Sample Input
2
3 1 2
4 1 10
Sample Output
85
369

Hint
In the first case, the third number is 85 = 2*1十2十3^4.
In the second case, the third number is 93 = 2*1十1*10十3^4 and the fourth number is 369 = 2 * 10 十 93 十 4^4.
大致题意:告诉你一个递推式,让你求它的第n项的值对2147493647取模

思路:递推式即为:f(n)=f(n-1)+2*f(n-2)+n^4,因为n很大,所以我们需要用矩阵快速幂来做。因为有个n^4,所以我们考虑用(n-1)^4,(n-1)^3,(n-1)^2,(n-1)^1,去维护n^4,n^3,n^2,n^1。经过推导可以发现:
n^1=(n-1)^1+1
n^2=(n-1)^2+2*(n-1)^1+1
n^3=(n-1)^3+3*(n-1)^2+(n-1)^1+1
n^4=(n-1)^4+4*(n-1)^3+6*(n-1)^2+4*(n-1)^1+1
Guessing the Dice Roll HDU - 5955 (矩阵快速幂+推导)_第1张图片

代码如下

#include
using namespace std;
#define LL long long int
const LL mod=2147493647;
struct matrix
{
    LL x[7][7];
};
matrix mutimatrix(matrix a,matrix b)
{
    matrix temp;
    memset(temp.x,0,sizeof(temp));

    for(int i=0;i<7;i++)
    for(int j=0;j<7;j++)
    for(int k=0;k<7;k++)
    {
        temp.x[i][j]+=a.x[i][k]*b.x[k][j]%mod;
        temp.x[i][j]%=mod;
    }
    return temp;
}
matrix k_powmatrix(matrix a,int n)
{
    matrix temp;
    memset(temp.x,0,sizeof(temp.x));
    for(int i=0;i<7;i++)
    temp.x[i][i]=1;

    while(n)
    {
        if(n&1)
        temp=mutimatrix(temp,a);

        a=mutimatrix(a,a);
        n>>=1;
    }
    return temp;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,a,b;
        scanf("%d%d%d",&n,&a,&b);
        if(n==1)
        {
            printf("%d\n",a);
            continue;
        }
        if(n==2)
        {
            printf("%d\n",b);
            continue;
        }
        matrix st;
        memset(st.x,0,sizeof(st.x));
        st.x[0][0]=1;
        st.x[1][0]=2;
        st.x[2][0]=1;
        st.x[3][0]=4;
        st.x[4][0]=6;
        st.x[5][0]=4;
        st.x[6][0]=1;

        st.x[0][1]=1;

        st.x[2][2]=1;
        st.x[3][2]=4;
        st.x[4][2]=6;
        st.x[5][2]=4;
        st.x[6][2]=1;

        st.x[3][3]=1;
        st.x[4][3]=3;
        st.x[5][3]=3;
        st.x[6][3]=1;

        st.x[4][4]=1;
        st.x[5][4]=2;
        st.x[6][4]=1;

        st.x[5][5]=1;
        st.x[6][5]=1;

        st.x[6][6]=1;

        matrix init;
        memset(init.x,0,sizeof(init.x));

        init.x[0][0]=b%mod;
        init.x[0][1]=a%mod;
        init.x[0][2]=16;
        init.x[0][3]=8;
        init.x[0][4]=4;
        init.x[0][5]=2;
        init.x[0][6]=1;

        st=k_powmatrix(st,n-2);
        st=mutimatrix(init,st);

        printf("%lld\n",(st.x[0][0]+mod)%mod);
    }
    return 0;
}

你可能感兴趣的:(矩阵快速幂)