zoukankan      html  css  js  c++  java
  • 矩阵快速幂的最简单用法

    矩阵快速幂

    链接:https://ac.nowcoder.com/acm/contest/1168/K
    来源:牛客网

    题目描述
    这个勇者明明超强却过分慎重,勇者龙宫院圣哉与n名冒险者一起去讨伐神秘魔物,龙宫院圣哉十分谨慎,他只会在最后一刻出手,
    每名冒险者轮流攻击魔物,冒险者的攻击有着某种规律,目前造成的总伤害是上一名冒险者攻击后造成的总伤害的4倍与上上名冒
    险者攻击后造成的总伤害的3倍之和,即当前总伤害f(n)=4f(n-1)+3f(n-2)(魔物的奇怪设定使总伤害忽高忽低),又由于异世界的奇异设定,冒险者们的总伤害
    不会超过666666,即对666666取模,龙宫院圣哉清楚的知道这个魔物的血量为m(m>666666),他想知道在所有的冒险者攻
    击完了以后,自己需要造成多少点伤害才能杀死魔物?目前第一名冒险者攻击后总共造成了4点伤害,第二名冒险者攻击后总共造
    成了233点伤害。
    输入描述:
    输入一行n,m,处理到文件结束

    666666<m<1e9
    2<n<1e9
    输出描述:
    输出一个整数
    示例1
    输入

    3 666667
    输出

    665723
    显然只是一道递推或者递归的题目。
    递归代码如下

    #include<iostream>
    #define mood 666666
    using namespace std;
    long long what(int n)
    {
    	if(n==1)
    		return 4;
    	else if(n==2)
    		return 233;
    	else
    		return (what(n-1)*4+what(n-2)*3)%mood; 
    }
    int main()
    {
    	long long n,sum;
    	while(cin>>n>>sum) {
    		cout<<sum-what(n)<<endl;
    	}
    }
    

    这种方法可处理n较小的情况,但是因为n最大可取到十亿,显然会超时,所以这里就用到了矩阵快速幂

    第一步构造矩阵
    在这里插入图片描述这样就构造了一个用于快速幂的矩阵,但是一定要注意构造的矩阵一定要是方阵,这样才能做多次相乘变换。

    #include<bits/stdc++.h>
    #define N 2               //由于这里只有两步递推关系,所以这里只要用一个2*2的矩阵
    typedef long long ll;
    #define mood 666666
    using namespace std;
    struct unit               //定义一个结构体后面便于设置二阶矩阵
    {
    	ll each[N][N];
    };
    unit what(unit a,unit b)					//用于矩阵相乘
    {
    	unit temp;
    	for(int i=0;i<N;i++)
    		for(int j=0;j<N;j++) {
    			temp.each[i][j]=0;
    			for(int k=0;k<N;k++) {
    				temp.each[i][j]+=a.each[i][k]*b.each[k][j];
    				temp.each[i][j]%=mood;
    			}
    		}
    	return temp;				//返回矩阵相乘的结果
    }
    int main()
    {
    	int s,sum;
    	while(cin>>s>>sum) {
    		if(s==1) {
    			cout<<sum-4<<endl;
    			continue;
    		}
    		else if(s==2) {
    			cout<<sum-233<<endl;
    			continue;
    		}
    		unit a,b;
    		a.each[0][0]=233,a.each[0][1]=4;		//初始化答案矩阵a
    		a.each[1][0]=0,a.each[1][1]=0;			//和用于快速幂的矩b
    		b.each[0][0]=4,b.each[0][1]=1;
    		b.each[1][0]=3,b.each[1][1]=0;
    		s-=2;
    		while(s>0) {
    			if(s&1)
    				a=what(a,b);
    			b=what(b,b);
    			s >>= 1;
    		}
    		cout<<sum-a.each[0][0]<<endl;
    	}	
    }
     
    

    这就是矩阵快速幂,在快速幂的基础上用一个矩阵来构造
    最主要的就是构造用于快速幂的矩阵,
    当然,我这里举的例子比较简单构造。

  • 相关阅读:
    《信息安全系统设计基础》实验四 驱动程序设计
    《信息安全系统设计基础》实验三 实时系统的移植
    20145338《信息安全系统设计基础》第十一周学习总结
    20145338 索朗卓嘎《信息安全系统设计基础》第10学习总结
    20145337 《信息安全系统设计基础》第十四周学习总结
    20145337《信息安全系统设计基础》第十三周学习总结
    20145337 GDB调试汇编堆栈过程分析
    20145337 《信息安全系统设计基础》第十二周学习总结
    20145337 《信息安全系统设计基础》实验五 网络通信
    20145337 《信息安全系统设计基础》实验三 实时系统的移植
  • 原文地址:https://www.cnblogs.com/lifehappy/p/12601208.html
Copyright © 2011-2022 走看看