怎麼題解全是線性基,來點高消做法。
Solution
性質:對矩陣進行初等變換(模 \(2\) 意義下),答案不變。
- 交換不用說。
- 一行加上另一行相當於異或兩行。記 \(x,y\) 是原來兩行的 \(1\) 個數,\(y'\) 是兩行異或後的 \(1\) 個數,容易發現 \(y'\equiv x+y\pmod 2\),證明就是異或只會減少成對的 \(1\)。那麼原來選了兩行,就把第一行刪掉;只選了第二行,就加入第一行。方案一一對應,答案不變。
- 一列加上另一列同理。
我們直接用高消消成對角線,記消完剩下 \(r\) 個 \(1\),答案就是:
\[2^{n+m-2r}\sum_{i=1}^{r}[i\bmod2=1]\binom{r}{i}3^{r-i}
\]
左邊的 \(2^{n+m-2r}\) 是為 \(0\) 的行列,隨便選;右邊列舉選中的 \(1\) 的個數 \(i\),從 \(r\) 箇中選出 \(1\) 個,剩下 \(r-i\) 個 \(1\) 只有不是行列同時選就行了,方案為 \(3^{r-i}\)。
用 bitset 最佳化,時間複雜度 \(\mathcal{O}(\dfrac{n^2m}{\omega})\)。
Code
namespace Milkcat {
using namespace Math;
typedef long long LL;
typedef pair<LL, LL> pii;
const int N = 305, mod = 998244353;
typedef Mint<mod> MI;
int n, m, x; MI ans;
bitset<N> A[N];
Combinations<MI> C;
int main() {
cin >> n >> m, C.init(n + m);
REP(i, 1, n) REP(j, 1, m)
cin >> x, A[i][j] = x;
int r = 0;
REP(k, 1, m) {
int t = 0;
REP(i, r + 1, n)
if (A[i][k]) t = i;
if (!t) continue;
r ++, swap(A[r], A[t]);
REP(i, 1, n)
if (i != r && A[i][k]) A[i] ^= A[r];
}
REP(i, 0, r)
if (i & 1) ans += C(r, i) * qpow((MI)3, r - i);
cout << ans * qpow((MI)2, n + m - r * 2) << '\n';
return 0;
}
}