2019牛客暑期多校训练营(第五场)generator 1 (十进制优化矩阵快速幂)

本文介绍了一种利用矩阵快速幂进行高效计算的优化方法,通过保留基本矩阵并使用十进制优化技巧,能够快速求解特定递推公式的大指数运算。文章提供了详细的代码实现和解释。

题意:

给了递推式,F[n]=a*F[n-1]+b*F[n-2] ,已知F[0] 和F[1],求F[n]

 

思路:

听了出题人的讲解,才知道矩阵快速幂还能这样的优化!

我们保留这四个最基本的矩阵:Matrix^1Matrix^2Matrix^4Matrix^8

那么怎么进行十进制优化呢?

举个例子:

比如:F[23],这个用十进制优化怎么求?

我们可以用保留的矩阵Matrix^1*Matrix^2来拼出23的低位的3

那么20怎么算出来呢?
这时候,我们就先拼出个10来:我们先让Matrix^1=Matrix^2*Matrix^8

这样我们的Matrix^1实际上就是原来的Matrix^1^0,然后我们在用Matrix^1^0来更新Matrix^2Matrix^4Matrix^8。这样就能通过这些来得到幂次是10~100的了。(真神奇)

 

代码:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=1e6+5;
ll mod;
char s[maxn];
struct Matrix
{
    ll a[2][2];
    Matrix(){
        memset(a,0,sizeof(a));
    }
    friend Matrix operator * (Matrix a, Matrix b)
    {
        Matrix tmp;
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    (tmp.a[i][j]+=(a.a[i][k]*b.a[k][j])%mod)%=mod;
                }
            }
        }
        return tmp;
    }
};
int main()
{
    ll x,y,a,b;
    scanf("%lld%lld%lld%lld",&x,&y,&a,&b);
    scanf("%s",s);
    scanf("%lld",&mod);
    int len=strlen(s);
    Matrix tmp[4],ans;
    tmp[0].a[0][0]=a;
    tmp[0].a[0][1]=b;
    tmp[0].a[1][0]=1;
    tmp[0].a[1][1]=0;
    tmp[1]=tmp[0]*tmp[0];
    tmp[2]=tmp[1]*tmp[1];
    tmp[3]=tmp[2]*tmp[2];
    ans.a[0][0]=ans.a[1][1]=1;
    for(int i=len-1;i>=0;i--){
        int x=s[i]-'0';
        for(int j=0;j<4;j++){
            if(x>>j&1){
                ans=ans*tmp[j];
            }
        }
        tmp[0]=tmp[1]*tmp[3];
        tmp[1]=tmp[0]*tmp[0];
        tmp[2]=tmp[1]*tmp[1];
        tmp[3]=tmp[2]*tmp[2];
    }
    printf("%lld\n",(ans.a[1][0]*y%mod+ans.a[1][1]*x%mod)%mod);
    return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值