ARC114E - Paper Cutting 2(组合数学,概率与期望)
ARC114E - Paper Cutting 2
Solution
考場上時間不夠,沒剛出來QAQ。
做法和官解本質相同,只是官解運用期望的線性性直接導出答案,而這里是對于所有方案統計貢獻在除以方案數,從期望的定義上計算答案。可能稍顯復雜。
Part one
我們要求的是合法操作序列的期望長度。
問題大概可以用一個類似《PKUWC2018獵人殺》的經典的套路轉化為:
設有一個W+H?2W+H-2W+H?2條線組成的排列p1p2...pnp_1p_2...p_np1?p2?...pn?,其中pip_ipi?的貢獻為111當且僅當不存在一個pj(j<i)p_j(j<i)pj?(j<i)可以把pip_ipi?叉掉,也就是說pip_ipi?前面沒有一個能結束游戲或者把pip_ipi?的那一半白紙去掉的數,否則pip_ipi?貢獻為000,一個排列的貢獻是所有數的貢獻和。
不難看出每個排列都映射到一組合法操作序列(即貢獻為111的pip_ipi?序列),每個排列的貢獻對應一組合法方案的長度,根據期望的定義(∑cipi\sum c_ip_i∑ci?pi?)容易證明上面所有排列的期望貢獻和就是我們要求的合法方案的長度和。
Part two
因此我們想要求所有W+H?2W+H-2W+H?2條線的(W+H?2)!(W+H-2)!(W+H?2)!種排列的期望貢獻,我們可以求出所有排列的貢獻再除以方案數。
于是問題變成怎么求(W+H?2)!(W+H-2)!(W+H?2)!種排列的貢獻和。
這里我們運用類似這場ARCARCARC的CCC題的方法,對于每個數,統計其對答案的貢獻。也就是考慮這個數xxx會在多少個排列里貢獻為111,即有多少個排列滿足在xxx之前不存在能叉掉xxx的數。
設行的編號為1,2,...,H?11,2,...,H-11,2,...,H?1列的編號為1,2,...,W?11,2,...,W-11,2,...,W?1,不妨令w1<w2,h1<h2w_1<w_2,h_1<h_2w1?<w2?,h1?<h2?(顯然這個順序沒有影響)。
先考慮列的貢獻,分類討論:
- 若x<w1x < w_1x<w1?,則前面不能出現在[x,w1)∪[w1,w2)[x,w_1)\cup[w_1,w_2)[x,w1?)∪[w1?,w2?)中的數。
- 若w1≤x<w2w_1 \leq x < w_2w1?≤x<w2?,則前面不能出現[w1,w2)[w_1,w_2)[w1?,w2?)中的數。
- 若x>w2x > w_2x>w2?,則前面不能出現在(w2,x]∪[w1,w2)(w_2,x]\cup[w_1,w_2)(w2?,x]∪[w1?,w2?)中的數。
對于第一種情況,我們枚舉xxx,再枚舉它在排列中的位置,貢獻即為:
∑i=1w1?1∑j=1W+H?2(W+H?2?((w2?1)?i+1)j?1)\sum_{i = 1}^{w_1-1}\sum_{j = 1} ^{W + H - 2}\binom{W+H-2-((w_2-1)-i+1)}{j - 1} i=1∑w1??1?j=1∑W+H?2?(j?1W+H?2?((w2??1)?i+1)?)
用上指標求和化簡得:
∑j=1W+H?2(W+H?2?w2+w1j)?(W+H?2?w2+1j)\sum_{j = 1} ^{W + H - 2}\binom{W+H-2-w_2+w_1}{j}-\binom{W+H-2-w_2+1}{j} j=1∑W+H?2?(jW+H?2?w2?+w1??)?(jW+H?2?w2?+1?)
這樣就可以O(W+H)O(W+H)O(W+H)計算了。
第二種和第三種是類似的,行的貢獻也是類似的,這里就不再贅述了。
總時間復雜度O(W+H)O(W+H)O(W+H)。
Code
實現上有一點點小細節。
//省略快讀和頭文件 int fac[MAXN], inv[MAXN]; inline int upd(int x, int y) { return x + y >= mods ? x + y - mods : x + y; } inline int quick_pow(int x, int y) {int ret = 1;for (; y ; y >>= 1) {if (y & 1) ret = 1ll * ret * x % mods;x = 1ll * x * x % mods;}return ret; } inline int C(int x, int y) { return (x < y || y < 0) ? 0 : 1ll * fac[x] * inv[y] % mods * inv[x - y] % mods; } void Init(int n) {fac[0] = 1;for (int i = 1; i <= n ; ++ i) fac[i] = 1ll * fac[i - 1] * i % mods;inv[n] = quick_pow(fac[n], mods - 2);for (int i = n - 1; i >= 0 ; -- i) inv[i] = 1ll * inv[i + 1] * (i + 1) % mods; } int solve(int n, int h1, int h2, int w1, int w2, int W) {int ans = 0;if (w1 > 1)for (int i = 2; i <= n - h2 + h1 - w2 + w1 ; ++ i)ans = upd(ans, 1ll * fac[n - i] * fac[i - 1] % mods * upd(C(n - h2 + h1 - w2 + w1, i), mods - C(n - h2 + h1 - w2 + 1, i)) % mods);if (w1 < w2)for (int i = 2; i <= n - h2 + h1 - w2 + w1 + 1; ++ i)ans = upd(ans, 1ll * fac[n - i] * fac[i - 1] % mods * C(n - h2 + h1 - w2 + w1, i - 1) % mods * (w2 - w1) % mods);if (w2 < W)for (int i = 2; i <= n - h2 + h1 - w2 + w1 ; ++ i)ans = upd(ans, 1ll * fac[n - i] * fac[i - 1] % mods * upd(C(n - h2 + h1 - w2 + w1, i), mods - C(n - h2 + h1 - W + w1, i)) % mods);return upd(ans, 1ll * (W - 1) * fac[n - 1] % mods); } signed main() { #ifndef ONLINE_JUDGEfreopen("a.in", "r", stdin); #endifint H, W, h1, w1, h2, w2, n; read(H), read(W), read(h1), read(w1), read(h2), read(w2), n = H + W - 2;if (w1 > w2) swap(w1, w2);if (h1 > h2) swap(h1, h2);Init(n);printf("%lld\n", 1ll * inv[n] * upd(solve(n, h1, h2, w1, w2, W), solve(n, w1, w2, h1, h2, H)) % mods);return 0; }總結
以上是生活随笔為你收集整理的ARC114E - Paper Cutting 2(组合数学,概率与期望)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CF997E. Good Subsegm
- 下一篇: CF1398F