2019牛客多校第五场 B(十进制矩阵快速幂)

传送门

题目就是求一个大指数幂矩阵快速幂的第 n n n

普通的二进制矩阵快速幂无法在给定的时间内跑完,所以将它转换成十进制的(涨姿势了!)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e6+5;
char n[maxn];
ll Mod;
ll x0,x1,a,b;
int len;
struct matrix{
    ll a[3][3]; //begin with 1
    friend matrix operator*(matrix A,matrix B)
    {
        matrix C;
        C.a[0][0] = C.a[0][1] = C.a[1][0] = C.a[1][1] = 0;
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
            	C.a[i][j]=0;
                for(int k=0;k<2;k++){
                    C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%Mod;
                }
            }
        }
        return C;
    }
};
 
 
matrix qpow(matrix A,int m)//方阵A的m次幂
{
    matrix ans;
    ans.a[0][1] = ans.a[1][0] = 0;
    for(int i=0;i<2;i++) ans.a[i][i]=1; //单位矩阵
    while(m)
    {
        if(m&1) ans=ans*A;
        A=A*A;
        m>>=1;
    }
    return ans;
}

matrix ppow(matrix x,char *b){
    len = strlen(b);
    matrix ans;
    ans.a[0][0] = x1,ans.a[0][1] = x0;
    int sub = 0;
    for(int i = len-1; i >= 0; i--){
    	int m = b[i]-'0';
		if(!sub){
			if(m > 0){
				m--;
				sub = 1;
			}
			else if(m == 0) m = 9;
		}
        if(m > 0){
            matrix tmp = qpow(x,m);
            ans = ans*tmp;
        }
        x = qpow(x,10);
    }
    return ans;
}


int main(){
    scanf("%lld%lld%lld%lld",&x0,&x1,&a,&b);
    scanf("%s%lld",n,&Mod);
    matrix f;
    
    //sub(n,one,mm);
    f.a[0][0] = a; f.a[0][1] = 1; f.a[1][0] = b; f.a[1][1] = 0;
    matrix ans = ppow(f,n);
    printf("%lld\n",ans.a[0][0]%Mod);
}
/*
1 1 1 1
1 1000007
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值