主要是因為預處理的範圍寫小,以及第一次寫帶刪除線性基,然後就調了好久/cy
如果把 \(a\) 看做一堆列向量,然後對於 \(c\) 的乙個列向量 \(v\) ,以及對應列的 \(b\) 的列向量 \(b'\),由矩陣分塊,可得以下式子:
\[v = (a_1 a_2 \dots a_q) b'
\]即 \(v\) 是由 \(a\) 線性組合出的。並且 \(c\) 的每個列向量也在 \(a\) 構成的線性空間裡。
固定 \(v\) 和 \(a\) ,可得 \(b\) 的數量有 \(2^\),其中 \(r = rank(a)\)
易得,對於確定的 \(v\) 和 \(a\), \(b\) 的數量是 \(2^\)
現在需要求 \(a\) 的數量。
因為 \(a\)
\(v\) 分別初等行變換 \(b\) 的解不變,所以對於秩相同的 \(v\) 都對應著相同的方案。
發現固定 \(v\) 求 \(r = r'\) 的 \(a\) 有多少比較麻煩。所以對每個固定的 \(a\) 求 \(v\) 的貢獻,然後再除掉 \(v\) 的個數。
記 \(f_\) 為 \(rank(a_) = r\) 的方案數,顯然對於乙個固定的 \(n\),可以 \(o(n^2)\) dp 出來,轉移只要討論是已經被表示還是乙個新的基。
列舉 \(r\) 易得 \(a\) 有 \(f_\) 個,對於 \(c\) 只有 \(a\) 的基線性組合有效,所以考慮變換一下基,變為 \(a\) 的 \(r\) 個基,此時 \(c\) 的方案數不變,為 \(f_\),其中 \(x = rank(c)\) (換基底就是乘上乙個可逆矩陣)
此時答案很好表示
\[\textrm = \sum_ \frac \times f_ \times 2 ^ }}
\]此時只要支援動態刪除的線性基即可。
我們維護每個向量是被哪幾個基異或出的。
考慮刪除時要找個基來頂替,有兩種情形:
存在乙個非基被它異或過,那麼直接異或不會降秩
不存在,則要找乙個基,此時要找最小的那個,不然會發生比它小的基會有多個擁有相同的最高位。
實現時考慮到刪除乙個基的時候,那個基的位置會被異或上選擇的那個基(根據異或性質)。
並且為了去掉要刪除的基的貢獻,同時計算新的基的貢獻,發現那個要刪除的會被貢獻兩次,即:
只要在被這個即將刪除的基異或過的位置異或上我們用來頂替的那個基即可。
同時我在一開始寫的時候寫麻煩了,實際上不需要乙個下標對應乙個基,因為刪除只和被哪些異或出有關。所以具體看**。
#include const int maxn = 1010;
const int mod = 1000000007;
typedef long long ll;
void reduce(int & x)
int mul(int a, int b)
int fastpow(int a, int b)
return res;
}typedef std::bitsetb;
b a[maxn], frm[maxn];
int rnk, bse[maxn], isb[maxn];
int n, p, m, q, typ;
void insert(int at, b x, int src) else
} a[at] = x, frm[at] = fx;
}int remove(int at)
int f[maxn][maxn], g[maxn][maxn], ansl[maxn], pow2[maxn * maxn];
void predo()
ran = std::min(n, p);
for (int i = std::min(n, m); ~i; --i)
}int main()
std::cout << ansl[rnk] << '\n';
while (q --> 0)
return 0;
}
集訓隊作業2018 喂鴿子
設 f n 表示有 n 只鴿子,每次等概率選乙隻喂,期望餵飽第一只鴿子的時間,f 表示有 n 只鴿子,已經喂了 m 次,此時這 n 只鴿子中沒有鴿子被餵飽的概率。ans sum n 1 f i f n sum sum f frac sum f sum frac 注意到有 dfrac n sum x ...
集訓隊作業2018 小Z的禮物
小水題。題意就是不斷隨機放乙個 1 times 2 骨牌,然後取走裡面的東西。求期望多少次取走所有的東西。然後有一維很小。首先顯然 minmax 容斥,將最後取走轉化為欽定一些物品,求第乙個取走的期望。然後顯然第乙個取走的期望只和剩下能蓋到物品的骨牌數有關。乙個骨牌能蓋到物品只和相鄰的兩個格仔是否欽...
集訓隊作業2018 GAME(並查集)
題意 題解 把這個dp式子給列出來 f i si max j f i s i max j fi si jmax 把這個字尾max max max記為m mm的話,每次就是m max m max m m max,考慮對於初始的每個m mm都維護一下,發現是條折線,維護一下這個折線,每次可以把小的一半合...