容斥
基本形態:
令 \(X\) 為所有 \(X_i\) 的集合,則可以簡便地寫成:
而在有些題目中,集合 \(X_{i_1}\cap X_{i_2}\cap X_{i_3}……X_{i_k}\) 的大小隻依賴於 \(k\) 而不依賴具體的 \(X\),那麼找到這些係數 \(a_0,a_1 \cdots a_n\) ,有公式:
煎蛋應用:錯位排列
列舉有多少個位置不滿足條件,那麼有容斥:
P6076 JSOI2015] 染色問題
有幾種限制顯然需要分開處理:
設 \(f_i\) 表示至多用 \(i\) 種顏色染棋盤的方案數。
那麼如果沒有前兩個限制那麼答案就是:
再考慮剩下兩種限制,設 \(g_{i,j}\) 表示 \(i\) 種顏色至多 \(j\) 列有顏色的方案數。
對於每一行,保證至少有一個數,每行的方案數為 \((i+1)^j-1\),一共有 \(n\) 行,那麼有:
再結合上面的式子即可。
P2567 SCOI2010] 幸運數字
這題其實比較平庸,主要是名字比較……
處理出所有隻有 \(6\) 和 \(8\) 的數,一共有 \(2^9\) 個數。
那麼直接列舉子集複雜度是爆的,但是主要到幾個數相乘很快貢獻會變成 \(0\)。
那麼 \(\text{DFS}\) 的時候如果大於了 \(b\) 退出即可。
P4448 AHOI2018初中組] 球球的排列
首先注意到如果 \(x\) 和 \(y\) 的乘積為平方數,\(y\) 和 \(z\) 的乘積為平方數,那麼 \(x\) 和 \(z\) 的乘積也是平方數。那麼一定可以將 \(n\) 若干個不交的等價類。
設可以劃分出 \(m\) 個不交集合,第 \(i\) 個集合有 \(a_i\) 個元素,請計數有多少個排列滿足排列中相鄰兩數不屬於同一集合。
其實也就相當於求的是有恰好 \(0\) 個相鄰點對屬於一個集合。
這種恰好往往是困難的,轉化為求至少有多少個相鄰點對再容斥。
再設 \(b_i\) 表示第 \(i\) 個集合有至少 \(b_i\) 個相鄰點對,再列舉 \(b_i\) 的總和,那麼有:
具體含義:
\(\displaystyle\prod_{i=1}^{n}{a_!}\):因為每個點的編號不同,所以答案要列舉全排列。
\((n-k)!\displaystyle\prod_{i=1}^{n}\dfrac{1}{(a_i-b_i)!}\):因為有 \(k\) 對相鄰點對屬於一個集合,也就相當於進行了一個繫結,那麼還剩下 \((n-k)\) 個動點,對於第 \(i\) 個集合有 \(a_i-b_i\) 個動點,動點又不區分,那麼也就有上式。
\(\displaystyle\prod_{i=1}^{n}\binom{a_i-1}{b_i}\):每個集合 \(a_i\) 個數要欽定至少 \(b_i\) 個數相鄰,選擇兩個數間的空隙視為這兩個數相鄰,一共有 \(a_i-1\) 個空隙。
\(-1^k\) 就是正常的容斥係數。
寫的時候就順次列舉 \(i\) 以及 \(b_i\) 實時維護係數的變化即可。
一種對子集狀態的容斥:
P3349 ZJOI2016] 小星星
首先有暴力:\(f_{i,j,S}\) 表示節點 \(i\) 對應著節點 \(j\),子樹內部集合為 \(S\) 的方案數,轉移的時候列舉每個兒子的所有狀態進行類似卷積的操作。
複雜度 \(O(n^3\times 3^n)\),被爆了。
注意到複雜度主要來自於列舉子集。考慮能否將子集那一位的狀態給刪掉。
注意到子集那一位唯一需要刻畫的是滿足所有數兩兩不同的性質,或者說 \(1 \sim n\) 每個數恰好都出現了一次。
那麼考慮將恰好一次轉化為至多一次,再配合上容斥轉移。列舉 \(1\sim n\) 的子集 \(S\) 表示欽定不在集合裡面的數不能出現。設 \(f_S\) 表示只考慮集合 \(S\) 裡面的數的答案。
對於每個內層的樹形 \(\text{dp}\) ,設 \(g_{x,i}\) 表示 \(x\) 的子樹中 \(x\) 對應著節點 \(i\) 的方案數,\(vis_{x,y}\) 表示是否原圖中 \(x\) 和 \(y\) 之間是否有連邊。
P9563 SDCPC2023] Be Careful 2
暴力的列舉子集是 \(2^k\) 顯然要被爆了。
首先注意到容斥的時候是列舉包含某個矩形的所有矩形的總面積。橫縱座標本質不同的個數只有至多 \(k\) 個,那麼至多有 \(k^4\) 個小矩形,轉化為列舉小矩形座標再反推貢獻。
然後再觀察 \(k^4\) 個小矩形的容斥係數,注意到只有 \(k^2\) 個左右的小矩形容斥係數不為 \(0\) ,原因在於如果一個矩形內部包含了其他點,那麼這個矩形一定是無貢獻的,原因在於選內部的這個點和不選內部的這個點分別會帶來 \(1\) 和 \(-1\) 的貢獻,剛好抵消。
所以只需要找出所有內部不包含其他點的矩形。
列舉左右邊界的點 \((x1,y1),(x2,y2)\),那麼下邊界只能是 \(\min(y1,y2)\) 或者是 \(x\in(x1,x2),y\in(0,min(y1,y2))\) 的點中 \(y\) 最大的點,因為如果選擇了不是最大的點,那麼最大點就會被包含在矩形內部。
最後考慮包含某個矩形的所有正方形的總面積。
把 \(min,max\) 拆開,變成分段函式,分別求字首和,細節依託,故從題單中刪除。
P8329 ZJOI2022] 樹
介紹一種偷雞的方法:你先寫個暴力,打個表出來看看,第一棵樹葉子集合為 \(S\) 的方案數和第二棵非葉子集合為 \(S\) 的方案數相等。感性理解下大概是兩者大概是個對稱關係,大概會存在一種對應方式。
代數證明非常困難,不多贅述。
那麼我們現在只用考慮一棵樹,設 \(f_S\) 表示第一棵樹中非葉子節點恰好為 \(S\) 的方案數。
直接計算依舊困難,考慮容斥,設 \(g_S\) 表示非葉子節點為 \(S\) 的子集的方案數。
那麼有:
答案為所有 \(f(S)\) 的平方和。
其實就可以做完了!具體而言,設 \(f_{i,j,k}\) 表示前 \(i\) 個點只考慮 \(|S\backslash T_1|,|S\backslash T_2|\) 的大小分別為 \(j,k\),考慮 \(f_{i-1,j,k}\) 能轉移到哪裡。
一共分五種情況,設 \(x=f_{i-1,j,k}\times j\times k\)
滾動陣列一下,然後你就切掉了很牛很牛的 \(\text{ZJOI2022}\)