DHUOJ2018033103(EKnight与路飞)矩阵快速幂

EKnight与路飞

Time Limit: 1000 ms  Memory Limit: 65535 KB

Description

有一天,帅气的EKnight去沙漠之国——阿拉巴斯坦,路遇被打败的路飞。EKnight决定帮助即将渴死的路飞。EKnight的技能是不断召唤雨云。前五次可以召唤的雨云含水量分别为1、2、1、2、1。
设f(n)为第n次的含水量,满足条件:f(n)=21*f(n-1)+20*f(n-2)+20*f(n-3)+19*f(n-4)+21*f(n-5),求解第n次的雨云含水量!
由于若降水量太大,会导致沙漠水土流失严重,热爱环境的EKnight决定让所有的雨云含水量对10000000求模。

The Input

输入一个n(1<=n<=1000000000)。

The Output

输出f(n)。

Sample Input

1
6
10

Sample Output

1
140
2370362

Author: EKnight
为自己写一篇题解……没错!题目是我出的…… 嘿嘿嘿 第一次出题写错了题面被队友吐槽……

作为AC率最高的题目……我果然不适合出题啊
数据很大,不可以暴力,直接套矩阵快速幂模板即可。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
struct matrix
{
    LL mat[15][15];
    matrix(){memset(mat,0,sizeof(mat));}
};
int mod=10000000;
matrix mul(matrix A,matrix B)
{
    int i,j,k;
    matrix C;
    for(i=1;i<=5;i++)
    {
        for(j=1;j<=5;j++)
        {
            for(k=1;k<=5;k++)
            {
                C.mat[i][j]+=(A.mat[i][k]*B.mat[k][j])%mod;
                C.mat[i][j]%=mod;
            }
        }
    }
    return C;
}
matrix powmul(matrix A,int k)
{
    matrix B;
    for(int i=1;i<=5;i++)
        B.mat[i][i]=1;
    while(k)
    {
        if(k&1)B=mul(B,A);
        A=mul(A,A);
        k>>=1;
    }
    return B;
}
LL a[1100];
int main()
{
    int n;
    a[1]=1;
    a[2]=2;
    a[3]=1;
    a[4]=2;
    a[5]=1;
    while(cin>>n&&n)
    {
        if(n<=5)
        {
            cout<<a[n]<<endl;
            continue;
        }
        matrix A;
        A.mat[1][1]=21;
        A.mat[1][2]=20;
        A.mat[1][3]=20;
        A.mat[1][4]=19;
        A.mat[1][5]=21;
        for(int i=2;i<=5;i++)
        {
            A.mat[i][i-1]=1;
        }
        matrix B;
        B=powmul(A,n-5);
        LL ans=0;
        ans=(ans+B.mat[1][1]%mod)%mod;
        ans=(ans+2*B.mat[1][2]%mod)%mod;
        ans=(ans+B.mat[1][3]%mod)%mod;
        ans=(ans+2*B.mat[1][4]%mod)%mod;
        ans=(ans+B.mat[1][5]%mod)%mod;
        cout<<ans<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值