本文主要根據之前講過的二分求冪,通過一道題目引入矩陣快速求冪的方法。先看下面的問題:[ jobdu-1443]
題目描述:題目的意思非常明確。可以立馬想到的是將矩陣的k次冪求出來,然後計算跡,最後求模即可。考慮到矩陣乘法的複雜度是o(n^3),k次冪要進行k-1次乘法。計算量較大。題目描述:
a為乙個方陣,則tr a表示a的跡(就是主對角線上各項的和),現要求tr(a^k)%9973。
輸入:
資料的第一行是乙個t,表示有t組資料。
每組資料的第一行有n(2 <= n <= 10)和k(2 <= k < 10^9)兩個資料。接下來有n行,每行有n個資料,每個資料的範圍是[0,9],表示方陣a的內容。
輸出:
對應每組資料,輸出tr(a^k)%9973。
樣例輸入:
2 2 2
1 0
0 1
3 99999999
1 2 3
4 5 6
7 8 9
樣例輸出:
2 2686
下面回顧下二分求冪的演算法:
power_integer(x, n)1 pow ← 1
2 while (n > 0)
3 do if (n mod 2 = 1)
4 then pow ← pow * x
5 x ← x * x
6 n ← n / 2
7 return pow
matrix& operator%(
int mod)
}return
*this;
}matrix fast_pow(matrix& a, int b)
a = (a%mod)*(a%mod);
b /= 2;
}return ans;
}
這一塊問題出在了,上面說道注意的第二點。矩陣做乘法的時候,中間的臨時結果可能會溢位。所以,應該及時求模,避免溢位。所以,改進的辦法是把求模換到乘法的地方。
#include
#include
#include
#define local
const
int maxn = 10;
const
int mod = 9973;
struct matrix
matrix( const matrix& rhs )
void init()}}
void set_diag( int val )}}
void print()
std::cout
<< std::endl;}}
matrix operator*( const matrix& b )}}
return ret;
}matrix& operator=( const matrix& b )
}return *this;
}matrix operator^(int b)
w = w*w;
b /= 2;
}return ans;
}int get_tr()}}
return ans;
}};int main()
}
還是改bug的事,現在真的發現了。改bug才是真正提高能力的時候。因為它同樣提高你分析能力的能力。找bug不是件容易的事。不過現在的心得還是,見到bug又能提高能力了。所以要積極。先圈定乙個小範圍,動手去試。 快速冪(矩陣快速冪)
求 3 0 3 1 3 n mod 1000000007 input 輸入乙個數n 0 n 10 9 output 輸出 計算結果 sample input 3sample output 40 分析 利用等比數列的求和公式得所求和是 3 n 1 1 2,如果暴力求3 n 1 會超時,這裡引入快速冪來...
快速冪 矩陣快速冪
快速冪 正常情況下求乙個數的冪時間複雜度為o n 而快速冪能把時間複雜度降到o logn 舉個例子 求5的13次方 思想首先把13化為二進位制 1101,即13 1101 8 1 4 1 2 0 1 1 即5 13 58 1 54 1 52 0 5 1 15 5 8 1 5 4 1 5 2 0 5 ...
快速冪 矩陣快速冪
快速冪 我們求a ba b ab最直接的方法就是把a乘b次這樣的話複雜度就是o n o n o n 但是在比賽時面對1e9的資料時還是會輕鬆超時的,此時就需要一種更快的乘法來幫助我們 我們把b拆成二進位制的形式得到a ba b ab a 10.01 a a1 0.01此時對b分解得到的序列10.01...