hdu 1757 A Simple Math Problem(矩阵快速幂)

来源:互联网 发布:大学生数据统计分析 编辑:程序博客网 时间:2024/06/07 03:09

http://acm.hdu.edu.cn/showproblem.php?pid=1757
题目大意:input x
If x < 10 f(x) = x.
If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);
And ai(0<=i<=9) can only be 0 or 1 .
输入k和m,求f(k)%m,a0~a9是用户输入的。
解题思路:因为k的范围是2*10^9而时间只有1秒,所以用题目上给的递推公式肯定会超时,所以这里我们可以构造一个矩阵,通过矩阵快速幂来求。
根据题意可构造如下矩阵:
这里写图片描述
而根据题目已知条件f(0)~f(9)等于0~9,其余直接用矩阵快速幂即可。
CODE:

#include <bits/stdc++.h>using namespace std;typedef long long ll;struct Matrix{    int m[10][10];};ll k,m;Matrix Init(int a[])///初始化所构造的矩阵{    int b[10][10] = {a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],                     1,0,0,0,0,0,0,0,0,0,                     0,1,0,0,0,0,0,0,0,0,                     0,0,1,0,0,0,0,0,0,0,                     0,0,0,1,0,0,0,0,0,0,                     0,0,0,0,1,0,0,0,0,0,                     0,0,0,0,0,1,0,0,0,0,                     0,0,0,0,0,0,1,0,0,0,                     0,0,0,0,0,0,0,1,0,0,                     0,0,0,0,0,0,0,0,1,0,};    Matrix s;    for(int i=0;i<10;i++)        for(int j=0;j<10;j++)            s.m[i][j] = b[i][j];   return s;}Matrix Mult(Matrix a,Matrix b)///计算两个矩阵相乘{    Matrix temp;    for(int i=0;i<10;i++)        for(int j=0;j<10;j++)            temp.m[i][j] = 0;    for(int i=0;i<10;i++)        for(int j=0;j<10;j++)        for(int k=0;k<10;k++)            temp.m[i][j] = (temp.m[i][j] + a.m[i][k]*b.m[k][j])%m;    return temp;}Matrix QuickPower(Matrix a,ll k)///矩阵快速幂{    Matrix ans,res;    res = a;    for(int i=0;i<10;i++)        for(int j=0;j<10;j++)           i==j? ans.m[i][j]=1:ans.m[i][j]=0;    while(k){        if(k&1)            ans = Mult(ans,res);        res = Mult(res,res);        k>>=1;    }    return ans;}int main(){    int a[10];    while(~scanf("%lld %lld",&k,&m)){        for(int i=0;i<10;i++)            scanf("%d",&a[i]);        Matrix s = Init(a);        if(k<10){            printf("%d\n",k%m);            continue;        }        Matrix temp = QuickPower(s,k-9);        ll ans = ((temp.m[0][0]*9)%m+(temp.m[0][1]*8)%m+(temp.m[0][2]*7)%m+(temp.m[0][3]*6)%m+(temp.m[0][4]*5)%m+(temp.m[0][5]*4)%m+(temp.m[0][6]*3)%m+(temp.m[0][7]*2)%m+(temp.m[0][8]*1)%m+(temp.m[0][9]*0)%m)%m;        ///根据计算矩阵的方法算出f(k)        printf("%lld\n",ans);    }    return 0;}
阅读全文
0 0
原创粉丝点击