HDU 4602 Partition

矩阵快速幂

#include<cstdio>

#include<cstring>

#include<cmath>

#include<map>

#include<algorithm>

using namespace std;



const long long MOD=1000000000+7;

long long n,k,RR,CC;

map<long long,long long>ans;

struct Matrix

{

    long long A[5][5];

    Matrix operator*(Matrix b);

};



Matrix Matrix::operator*(Matrix b)

{

    Matrix c;

    long long i,j,k;

    memset(c.A,0,sizeof(c.A));

    for(i=1;i<=RR;i++)

        for(j=1;j<=CC;j++)

            for(k=1;k<=3;k++)

                c.A[i][j]=(c.A[i][j]+(A[i][k]*b.A[k][j]+MOD)%MOD)%MOD;

    return c;

}



int main()

{

    ans.clear();

    ans[1]=1;ans[2]=2;ans[3]=5,ans[4]=12;

    int T;

    scanf("%d",&T);

    while(T--)

    {

        scanf("%lld%lld",&n,&k);

        if(k>n) {printf("0\n");continue;}

        long long u=n-k+1;

        if(ans[u]!=0) printf("%lld\n",ans[u]);

        else

        {

            long long i,j;

            long long b=u-4;

            Matrix JZ;

            JZ.A[1][1]=4;JZ.A[1][2]=0;JZ.A[1][3]=0;

            JZ.A[2][1]=-4;JZ.A[2][2]=4;JZ.A[2][3]=1;

            JZ.A[3][1]=0;JZ.A[3][2]=-4;JZ.A[3][3]=0;

            Matrix C;

            for(i=1;i<=3;i++)

                for(j=1;j<=3;j++)

                {

                    if(i==j) C.A[i][j]=1;

                    else C.A[i][j]=0;

                }

            RR=3;CC=3;

            while(b>0)

            {

                if(b%2==1)C=C*JZ,b--;

                else JZ=JZ*JZ,b=b/2;

            }



            RR=1;CC=3;

            Matrix CS;

            CS.A[1][1]=ans[4];

            CS.A[1][2]=ans[3];

            CS.A[1][3]=ans[2];

            CS=CS*C;

            ans[u]=CS.A[1][1];

            printf("%lld\n",ans[u]);

        }

    }

    return 0;

}

 

你可能感兴趣的:(partition)