生活随笔
收集整理的這篇文章主要介紹了
矩阵快速幂的最简单用法
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
矩陣快速冪
鏈接:https://ac.nowcoder.com/acm/contest/1168/K 來源:??途W
題目描述 這個勇者明明超強卻過分慎重,勇者龍宮院圣哉與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;elsereturn (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; //初始化答案矩陣aa.each[1][0]=0,a.each[1][1]=0; //和用于快速冪的矩bb.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;}
}
這就是矩陣快速冪,在快速冪的基礎上用一個矩陣來構造 最主要的就是構造用于快速冪的矩陣, 當然,我這里舉的例子比較簡單構造。
總結
以上是生活随笔 為你收集整理的矩阵快速幂的最简单用法 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。