• Uva10870 Recurrences(矩阵快速幂)


    题目

    考虑递推关系式(f(n)=a1*f(n-1)+a2*f(n-2)+....+ad*f(n-d)),计算f(n)%m

    【输入格式】 输入包含多组测试数据。每组数据第一行为三个整数d,n,m(1<=d<=15,1<=n<=2^31-1,1<=m<=46340)。第二行包含d个非负整数a1,a2.....ad。第三行为d个非负整数f(1),f(2).....f(d)。这些数字均不超过2^31-1。输入结束的标志是d=n=m=0.

    【输出格式】 对于每组数据,输出f(n)%m

    思路

    前置知识是矩阵乘法和矩阵快速幂。

    矩阵相乘最重要的方法是一般矩阵乘积。它只有在第一个矩阵的栏数(column)和第二个矩阵的列数(row)相同时才有定义。一般单指矩阵乘积时,指的便是一般矩阵乘积。若A为m×n矩阵,B为n×p矩阵,则他们的乘积AB会是一个m×p矩阵。

    公式

    而矩阵快速幂对于n*n的方针多次进行自己乘自己的迭代运算,同样可以用数的快速幂优化。

    举例来说,对于本题而言

    (F[n]=(f[n-d+1],f[n-d+2],f[n-d+3]....f[n]))

    接下来要构造矩阵A,使得(F[n]=F[n-1]*A)

    简单笔算一下可知:

    这样代码也不难写出了,注意:矩阵相乘不满足交换律!!!!

    代码

    #include<bits/stdc++.h>
    #define M 25
    #define LL long long
    using namespace std;
    int d,x,mod;
    struct Matrix{
    	int n,m,a[M][M];
    	void clear(){memset(a,0,sizeof(a));}
    	void resize(int _n,int _m){n=_n;m=_m;}
    	Matrix operator *(const Matrix &_)const{
    		Matrix res;res.resize(n,_.m);
    		for(int i=1;i<=n;i++){
    			for(int j=1;j<=_.m;j++){
    				res.a[i][j]=0;
    				for(int k=1;k<=m;k++){
    					res.a[i][j]+=1LL*a[i][k]*_.a[k][j]%mod;
    					if(res.a[i][j]>=mod)res.a[i][j]-=mod;	
    				}
    			}
    		}
    		return res;
    	}
    }Ma,F_d;
    Matrix qkpow(Matrix a,int b){
    	Matrix res;res.clear();res.resize(a.n,a.n);
    	for(int i=1;i<=a.n;i++)res.a[i][i]=1;
    	while(b){if(b&1)res=res*a;a=a*a;b>>=1;}
    	return res;
    }
    int A[M],f[M];
    int main(){
    	while(scanf("%d%d%d",&d,&x,&mod)&&(d!=0&&x!=0&&mod!=0)){
    		for(int i=1;i<=d;i++)scanf("%d",&A[i]),A[i]%=mod;
    		for(int i=1;i<=d;i++)scanf("%d",&f[i]),f[i]%=mod;
    		if(x<=d){printf("%d
    ",f[x]);continue;}
    		Ma.clear();Ma.resize(d,d);
    		for(int i=2;i<=d;i++)Ma.a[i-1][i]=1;
    		for(int i=1;i<=d;i++)Ma.a[d][i]=A[d-i+1];
    		F_d.clear();F_d.resize(d,1);
    		for(int i=1;i<=d;i++)F_d.a[i][1]=f[i];
    		Matrix ans=qkpow(Ma,x-d)*F_d;
    		printf("%d
    ",ans.a[d][1]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    linux下的watch命令
    Erlang运行时的错误
    Redis查看帮助文档
    PO Box简介
    用erlang写的kmp算法
    laravel全过程
    artdialog 弹出框
    支持触屏版的旋转幻灯片
    android生成APP的名字,图标,开机动画
    使用Eclipse构建app网站应用
  • 原文地址:https://www.cnblogs.com/zryabc/p/10359990.html
Copyright © 2020-2023  润新知