hdu 1005(矩陣快速冪)
阿新 • • 發佈:2018-12-12
題目描述的是一個遞推,並且沒有其他變數與n有關,是一個典型的矩陣快速冪模板題(有多種解法,只提這一種)。
{1,1} * A{A,1} = {f(n),f(n-1)}
{B,0}
/** 矩陣快速冪 模板 **/ #include <algorithm> #include <iostream> #include <cstring> #include <string> #include <vector> #include <cmath> #include <deque> #include <map> #define For(i,a,b) for(i = a;i < b;i ++) #define For_(i,a,b) for(i = a;i > b; i --) #define Max 100 using namespace std; typedef long long ll; int Nnum;//矩陣的大小 ,預設為 Nnum * Nnum,這樣很好計算 ,從零開始 int Mod = 7;//取模的大小 typedef struct node{//Array 在前,* 的在後 ll Array[Max][Max]; node operator * (node a){ int i,j,k; node ans; For(i,0,Nnum+1){ For(j,0,Nnum+1){ ans.Array[i][j] = 0; } } For(k,0,Nnum +1){//k 在外面可以剪枝 0 的運算 For(i,0,Nnum +1){ if(Array[i][k] != 0) For(j,0,Nnum +1){ if(a.Array[k][j] != 0){ ans.Array[i][j] =(ans.Array[i][j] + Array [i][k] * a.Array[k][j] % Mod) % Mod; } } } } return ans; } }Node; void Print(node a){ // 輸出 矩陣 int i,j; For(i,0,Nnum+1){ For(j,0,Nnum+1){ cout<<a.Array[i][j]<<" "; } cout<<endl; } } node Clear(){// 矩陣 初始化 node a; int i,j,k; For(i,0,Nnum+1){ For(j,0,Nnum+1){ a.Array[i][j] = (i == j); } } return a; } node ArrayQuit(node ans,node a,int N){//快速冪 while(N){ if(N & 1)ans = (ans * a); a = (a * a); N >>= 1; } return ans; } /* 1 1 3 1 2 10 0 0 0 */ int main(){ Nnum = 9;//初始化 Nnum Nnum 是矩陣的規模 int i,j,k,n,a,b; node Array; while(scanf("%d%d%d",&a,&b,&n)==3){ if(a==0&&b==0&&n==0)break; if(n < 3){ printf("1\n"); continue; } Array.Array[0][0] = a,Array.Array[0][1] = 1,Array.Array[1][0] = b,Array.Array[1][1]= 0; node ans; ans.Array[0][0]=1,ans.Array[0][1] = 1; // Print(ans); ans = ArrayQuit(ans,Array,n-2); // cout<<"ans:\n"; // Print(ans); printf("%d\n",ans.Array[0][0]); } return 0; }