HDU-1757-A Simple Math Problem

Lele now is thinking about a simple function f(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 .
Now, I will give a0 ~ a9 and two positive integers k and m ,and could you help Lele to caculate f(k)%m.
Input
  The problem contains mutiple test cases.Please process to the end of file.
In each case, there will be two lines.
In the first line , there are two positive integers k and m. ( k<2*10^9 , m < 10^5 )
In the second line , there are ten integers represent a0 ~ a9.
Output
  For each case, output f(k) % m in one line.
Sample Input
10 9999
1 1 1 1 1 1 1 1 1 1
20 500
1 0 1 0 1 0 1 0 1 0
Sample Output
45
104

距阵关系图
解释:
首先 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10),所以矩阵数组的宽度和长度应为10;
输入a0–a9:
输入在矩阵的第一行,作为F9

for(int i=0;i<10;i++)
            scanf("%lld",&a.nmb[0][i]);

初始化:

for(int i=1;i<10;i++)
            a.nmb[i][i-1] = 1;
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
const int maxn = 100;
typedef long long ll;
using namespace std;
ll k,m;
struct In{
    ll nmb[maxn][maxn];
};
In _mul(In x,In y){
    In ans;
    memset(ans.nmb,0,sizeof(ans.nmb));
    for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            for(int k=0;k<10;k++){
                ans.nmb[i][j] = (ans.nmb[i][j]+x.nmb[i][k]*y.nmb[k][j]%m)%m;
            }
        }
    }
    return ans;
}
In _pow(In x,int p){
    In ans;
    for(int i=0;i<10;i++){
        for(int j=0;j<10;j++){
            if(i==j) ans.nmb[i][j] = 1;
            else ans.nmb[i][j] = 0;
        }
    }
    while(p){
        if(p&1) ans = _mul(ans,x);
        p >>= 1;
        x = _mul(x,x);
    }
    return ans;
}
int main(void)
{
    while(~scanf("%lld%lld",&k,&m)){
        In a,ans;
        memset(a.nmb,0,sizeof(a.nmb));
        for(int i=0;i<10;i++)
            scanf("%lld",&a.nmb[0][i]);
        for(int i=1;i<10;i++)
            a.nmb[i][i-1] = 1;
        if(m<10)   printf("%lld\n",m%k);
        else{
            ans = _pow(a,k-9);
            ll mm=0;
            for(int i=0;i<10;i++)
                mm = (mm+ans.nmb[0][i]*(9-i)%m)%m;
            printf("%lld\n",mm);
        }
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逃夭丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值