bitset 優化 01 矩乘

2022-09-10 07:30:10 字數 1225 閱讀 7331

這裡的矩乘並不狹隘地專指一般矩陣乘法,而可以指所有與一般矩乘一樣具有結合律的二元矩陣運算

例:定義一種 01 矩陣乘法 \(a\cdot b=c\) 為下面的 c++ **

for (int i = 1; i <= n; ++i)

for (int j = 1; j <= n; ++j)

for (int k = 1; k <= n; ++k)

c[i][j] |= a[i][k] & b[k][j];

其中 \(a,b,c\) 都是 01 矩陣。

顯然這種矩乘是具有結合律的,即符合 \((a\cdot b)\cdot c=a\cdot(b\cdot c)\)

因為是 01 矩陣,可以用 bitset 優化

於是上面的**顯然與下面這份等價

std::bitseta[n], b[n], c[n];

for (int i = 1; i <= n; ++i)

for (int k = 1; k <= n; ++k)

for (int j = 1; j <= n; ++j)

if (a[i][k])

c[i][j] |= b[k][j];

即交換一下 k 與 j 的迴圈。

仔細一看,發現最後一維列舉 j 時,a[i][k]不受其影響,同時c[i]b[k]對齊了

於是利用 bitset 自帶的運算我們可以寫成

std::bitseta[n], b[n], c[n];

for (int i = 1; i <= n; ++i)

for (int k = 1; k <= n; ++k)

if (a[i][k])

c[i] |= b[k];

因為 stl 封裝的內部優化肯定比我們自己在外部手寫的優很多

或者更準確地說

時間複雜度從 \(o(n^3)\) 降為了 \(o(n^3/\omega)\) ,其中一般 \(\omega\) 為 32 或 64 ,與計算機位數有關。

一些例題:

cf567d flights for regular customers

usaco07nov cow relays g

noi online #3 提高組 魔法值

noi2020 美食家

Sajam(01翻轉 bitset優化)

原題 題意 n n的01矩陣,你可以無限次翻轉一行或者一列,可以最多翻轉k k n 次乙個點。問是否可以全部翻轉成0。解析 k n說明至少有一行不會被翻轉單個點,或者k n時每行翻轉乙個點。那麼列舉每一行為那一行,將其他行與之對比 可以翻轉後再對比 不同的數量就是需要翻轉單個點的數量。因為有列翻轉,...

數學蒟蒻的矩乘小結

a b a b left 1 2 3 4 5 6 end right left 1 4 2 5 3 6 end right left 14 32 32 77 end right a b 1 23 4 56 a b a ba b的理解是,b bb矩陣是2 22個3 33維向量,a aa矩陣提供了3 3...

CF575A Fibonotci(矩乘套路題)

點此看題面 假設 m 0 則第 i 個位置的轉移矩陣就是 begin 0 s 1 s end 那麼就是要求第 2 sim k 個矩陣的總乘積,顯然發現它的週期為 n 這種東西隨便做做就好了,相信大家都會,畢竟並不是此題的核心所在。考慮乙個給定的 s i 影響到的是 s 和 s 因此我們可以找出 2m...