HDU 4565——So Easy!(矩阵快速幂乘法)

35 篇文章 0 订阅

转载请注明出处:http://blog.csdn.net/u010734277




用矩阵乘C1和C0而不是C2和C1是因为求C2的时候要数据类型转换,转换时间很长,会超时

下面是代码

#include<iostream>
#include<math.h>
#include<string.h>
#include<stdio.h>
using namespace std;
__int64 m;
typedef struct Matrix{
    __int64 row[4][4];
}matrix;

matrix multi(matrix a,matrix b){
    matrix c;
    memset(c.row,0,sizeof(c.row));
    for(int i=0;i<=1;++i){
        for(int t=0;t<=1;++t){
            for(int h=0;h<=1;++h){
                c.row[i][t]+=a.row[i][h]*b.row[h][t];
                c.row[i][t]=(c.row[i][t]%m+m)%m;
            }
        }
    }
    return c;
}

matrix multi_pow(matrix a,__int64 n){
    matrix c;
    memset(c.row,0,sizeof(c.row));
    c.row[0][0]=1;
    c.row[1][1]=1;
    matrix t=a;
    while(n){
        if(n&1)c=multi(c,t);
        t=multi(t,t);
        n>>=1;
    }
    return c;
}

int main(){
    __int64 a,b,n;
    while(scanf("%I64d%I64d%I64d%I64d",&a,&b,&n,&m)!=EOF){
        __int64 numn;
        __int64 numn_1;
        __int64 num0=2;
        __int64 num1=2*a;
        matrix A;
        A.row[0][0]=2*a;
        A.row[0][1]=b-a*a;
        A.row[1][0]=(__int64) 1;
        A.row[1][1]=(__int64) 0;
        A=multi_pow(A,n-1);
        numn=A.row[0][0]*num1+A.row[0][1]*num0;
        if(n>2)
        printf("%I64d\n",numn%m);
        else if(n==1){
        printf("%I64d\n",num1%m);
        }
        else if(n==2){
        printf("%I64d\n",numn%m);
        }
    }
    return 0;
}



巩固一下~~

用矩阵快速幂实现

来源 zxp学长

#include<iostream>
#include<stdlib.h>
using namespace std;

typedef struct Matrix{
	double row[4][4];
}matrix;

matrix multi(matrix a,matrix b){
	matrix c;
	memset(c.row,0,sizeof(c.row));
	for(int i=0;i<=1;++i){
		for(int j=0;j<=1;++j){
			for(int k=0;k<=1;++k){
				c.row[i][j]+=a.row[i][k]*b.row[k][j];
			}
		}
	}
	return c;
}

matrix pow_multi(matrix a,int n){
	matrix c;
	memset(c.row,0,sizeof(c.row));
	c.row[0][0]=c.row[1][1]=1;
	while(n){
		if(n&1)c=multi(c,a);
		a=multi(a,a);
		n>>=1;
	}
	return c;
}

int main(){
	Matrix A;
	double x,y;
	A.row[0][0]=2;
	A.row[0][1]=-1;
	A.row[1][0]=1.5;
	A.row[1][1]=-0.5;
	A=pow_multi(A,1000);
	x=-A.row[0][0]+A.row[0][1];
	y=-A.row[1][0]+A.row[1][1];
	cout<<x<<' '<<y<<endl;
	return 0;
}

下面是数学方法


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值