日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【集训队作业2018】围绕着我们的圆环

發(fā)布時間:2025/7/14 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【集训队作业2018】围绕着我们的圆环 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我貌似開始爆OJ了

主要是因為預(yù)處理的范圍寫小,以及第一次寫帶刪除線性基,然后就調(diào)了好久/cy

如果把 \(A\) 看做一堆列向量,然后對于 \(C\) 的一個列向量 \(V\) ,以及對應(yīng)列的 \(B\) 的列向量 \(B'\),由矩陣分塊,可得以下式子:

\[ V = (A_1 A_2 \dots A_q) B' \]

\(V\) 是由 \(A\) 線性組合出的。并且 \(C\) 的每個列向量也在 \(A\) 構(gòu)成的線性空間里。

固定 \(V\)\(A\) ,可得 \(B\) 的數(shù)量有 \(2^{q - r}\),其中 \(r = rank(A)\)

易得,對于確定的 \(V\)\(A\)\(B\) 的數(shù)量是 \(2^{s(q - r)}\)

現(xiàn)在需要求 \(A\) 的數(shù)量。

因為 \(A\) \(V\) 分別初等行變換 \(B\) 的解不變,所以對于秩相同的 \(V\) 都對應(yīng)著相同的方案。

發(fā)現(xiàn)固定 \(V\)\(r = r'\)\(A\) 有多少比較麻煩。所以對每個固定的 \(A\)\(V\) 的貢獻,然后再除掉 \(V\) 的個數(shù)。

\(f_{n,m,r}\)\(rank(A_{n,m}) = r\) 的方案數(shù),顯然對于一個固定的 \(n\),可以 \(O(n^2)\) DP 出來,轉(zhuǎn)移只要討論是已經(jīng)被表示還是一個新的基。

枚舉 \(r\) 易得 \(A\)\(f_{p,q,r}\) 個,對于 \(C\) 只有 \(A\) 的基線性組合有效,所以考慮變換一下基,變?yōu)?\(A\)\(r\) 個基,此時 \(C\) 的方案數(shù)不變,為 \(f_{r,s,x}\),其中 \(x = rank(C)\) (換基底就是乘上一個可逆矩陣)

此時答案很好表示

\[\textrm{Ans} = \sum_{r = x} \frac{f_{p,q,r} \times f_{r,s,x} \times 2 ^ {s(q - r)}}{f_{p,s,x}}\]

此時只要支持動態(tài)刪除的線性基即可。

我們維護每個向量是被哪幾個基異或出的。

考慮刪除時要找個基來頂替,有兩種情形:

  • 存在一個非基被它異或過,那么直接異或不會降秩
  • 不存在,則要找一個基,此時要找最小的那個,不然會發(fā)生比它小的基會有多個擁有相同的最高位。
  • 實現(xiàn)時考慮到刪除一個基的時候,那個基的位置會被異或上選擇的那個基(根據(jù)異或性質(zhì))。

    并且為了去掉要刪除的基的貢獻,同時計算新的基的貢獻,發(fā)現(xiàn)那個要刪除的會被貢獻兩次,即:

    只要在被這個即將刪除的基異或過的位置異或上我們用來頂替的那個基即可。

    同時我在一開始寫的時候?qū)懧闊┝?#xff0c;實際上不需要一個下標對應(yīng)一個基,因為刪除只和被哪些異或出有關(guān)。所以具體看代碼。

    #include <bits/stdc++.h>const int MAXN = 1010; const int mod = 1000000007; typedef long long LL; void reduce(int & x) { x += x >> 31 & mod; } int mul(int a, int b) { return (LL) a * b % mod; } int fastpow(int a, int b) {int res = 1;while (b) {if (b & 1) res = mul(res, a);a = mul(a, a);b >>= 1;}return res; } typedef std::bitset<MAXN> B; 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) {static B fx; fx.reset(); fx[src] = true;isb[at] = 0;for (int i = m; i; --i) if (x.test(i)) {if (bse[i]) {x ^= A[bse[i]];fx ^= frm[bse[i]];} else {bse[i] = at;isb[at] = i;++rnk;break;}}A[at] = x, frm[at] = fx; } int remove(int at) {int ax = 0; isb[0] = 1001;for (int i = 1; i <= n; ++i)if (frm[i].test(at))if (isb[i] < isb[ax]) ax = i;rnk -= (bool) isb[ax];for (int i = 1; i <= n; ++i)if (i != ax && frm[i].test(at))frm[i] ^= frm[ax], A[i] ^= A[ax];if (isb[ax]) bse[isb[ax]] = 0;return ax; }int f[MAXN][MAXN], g[MAXN][MAXN], ansl[MAXN], pow2[MAXN * MAXN]; void predo() {pow2[0] = f[0][0] = g[0][0] = 1;int ran = std::max(n, m * P);for (int i = 1; i <= ran; ++i)reduce(pow2[i] = pow2[i - 1] * 2 - mod);ran = std::max(std::max(n, m), P);for (int i = 0; i < ran; ++i)for (int j = 0; j <= i; ++j) {reduce(f[i + 1][j] += mul(f[i][j], pow2[j]) - mod);reduce(f[i + 1][j + 1] += mul(f[i][j], pow2[n] - pow2[j] + mod) - mod);reduce(g[i + 1][j] += mul(g[i][j], pow2[j]) - mod);reduce(g[i + 1][j + 1] += mul(g[i][j], pow2[m] - pow2[j] + mod) - mod);}ran = std::min(n, P);for (int i = std::min(n, m); ~i; --i) {int & ans = ansl[i] = 0;for (int x = i; x <= ran; ++x)reduce(ans += (LL) f[P][x] * g[x][i] % mod * pow2[m * (P - x)] % mod - mod);ans = mul(ans, fastpow(f[m][i], mod - 2));} } int main() {std::ios_base::sync_with_stdio(false), std::cin.tie(0);std::cin >> n >> P >> m >> Q >> typ;predo();B tx;for (int i = 1; i <= n; ++i) {tx.reset();for (int j = 1, t; j <= m; ++j)std::cin >> t, tx[j] = t;insert(i, tx, i);}std::cout << ansl[rnk] << '\n';while (Q --> 0) {int at, t;std::cin >> at; at ^= typ * ansl[rnk];tx.reset();for (int j = 1; j <= m; ++j)std::cin >> t, tx[j] = t;insert(remove(at), tx, at);std::cout << ansl[rnk] << '\n';}return 0; }

    轉(zhuǎn)載于:https://www.cnblogs.com/daklqw/p/11508682.html

    總結(jié)

    以上是生活随笔為你收集整理的【集训队作业2018】围绕着我们的圆环的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。