HDU 4990 Reading comprehension(构造矩阵)

题目链接:
HDU 4990 Reading comprehension

/*
 *题意:
 *规定:当n为偶数时a[n]=2*a[n-1],n为奇数时a[n]=2*a[n-1]+1(n>1),且a[0]=0.
 *给出n和m求出a[n]%m的值,其中1<=n,m<=1e9.
 *
 *分析:
 *由于n,m太大,时间限制是1000ms,如果是普通的递推的话,应该会TLE。所以用矩阵解决
 *构造矩阵
 *   0 1 0        0 
 * A=1 0 0  和 B= 1 
 *   0 1 2       a[0] 
 * 然后用A^n乘以矩阵B得到矩阵C,答案就是C[3][1]。
 */

//1424K 15MS
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

long long n,m;

struct Matrix{
    int row,col;
    long long data[15][15];
};

void init(Matrix& x)
{
    x.row=x.col=3;
    x.data[1][2]=x.data[2][1]=x.data[3][2]=1;
    x.data[1][1]=x.data[1][3]=x.data[2][2]=x.data[2][3]=x.data[3][1]=0;
    x.data[3][3]=2;
}

Matrix multiply(Matrix a,Matrix b,long long mod)
{
    Matrix ans;
    ans.row=a.row;
    ans.col=b.col;
    memset(ans.data,0,sizeof(ans.data));
    for(int i=1;i<=ans.row;i++){
        for(int j=1;j<=ans.col;j++){
            for(int k=1;k<=a.col;k++){
                ans.data[i][j]+=a.data[i][k]*b.data[k][j];
                ans.data[i][j]%=mod;
            }
        }
    }
    return ans;
}

Matrix quick_power(Matrix a,long long n,long long m)
{
    Matrix ans,tmp=a;
    ans.row=a.row,ans.col=a.col;
    memset(ans.data,0,sizeof(ans.data));
    for(int i=1;i<=ans.row;i++) ans.data[i][i]=1;
    while(n){
        if(n&1) ans=multiply(ans,tmp,m);
        tmp=multiply(tmp,tmp,m);
        n>>=1;
    }
    return ans;
}

int main()
{
    while(~scanf("%I64d %I64d",&n,&m)){
        Matrix a,b;
        init(a);
        a=quick_power(a,n,m);
        b.row=3,b.col=1;
        b.data[1][1]=0,b.data[2][1]=1,b.data[3][1]=0;
        b=multiply(a,b,m);
        printf("%I64d\n",b.data[3][1]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值