1. 程式人生 > >容斥原理證明及應用

容斥原理證明及應用

普通的容斥原理

例題

給定平面上n個多邊形,請求出其覆蓋的總面積。
n 10 ,  

50 , 000 n\le 10,~邊數\le 50,000

解決方案1——自適應辛普森積分

該方法適應於大部分求覆蓋面積的問題,但是由於精度問題,不易於實現。

解決方案2——按點座標離散化

該方法實現較為複雜,在多邊形數量多的時候佔優勢,但是邊數很多的情況下就顯得力不從心了(但是似乎也是可以做到 O

( n m + m l o g m )
O(nm+mlogm)
的)。

解決方案3——容斥原理

考慮如果我們直接把所有多邊形面積求出來然後求和,會多算一些重複覆蓋的地方。於是我們可以考慮把它們全部去掉。但是如果直接列舉兩個多邊形求交,又會多減去一些東西,於是考慮再把它加回來……
這樣就可以得到容斥原理的公式了——
a n s = A S ( 1 ) A 1 A r e a ( A ) ans=\sum_{A\subseteq S}(-1)^{|A|-1}·Area(A)
其中 S S 為所有多邊形的集合, A r e a ( x ) Area(x) 函式表示集合 x x 中所有多邊形的交的面積。
說人話就是暴力列舉選出一些多邊形,計算它們交的面積。如果選出了奇數個多邊形,就拿答案加上它,否則減去它。
這樣就得到了一個非常難以理性感知的容斥原理,為了能夠深入理解它,我們需要證明。

證明

考慮原來那麼多多邊形將平面分成了很多部分,每個部分是一個小多邊形,這些小多邊形互不相交(除了邊)。我們最後需要求出的面積實際上就是每個小多邊形的面積。考慮小多邊形 x x 在容斥原理中被如何處理,它被統計的面積是:
x A   a n d   A S ( 1 ) A 1 A r e a ( x ) \sum_{x\in A~and~A\subseteq S}(-1)^{|A|-1}Area(x)
換一種表示方案,假設它被包含在了 k k 的原來的多邊形中,那麼它會被統計的次數是:
i = 1 k ( k i ) ( 1 ) i 1 = i = 0 k ( k i ) ( 1 ) i + 1 = 1 0 k = 1 \sum_{i=1}^k\binom ki(-1)^{i-1}=-\sum_{i=0}^k\binom ki(-1)^i+1=1-0^k=1
也就是說每個小多邊形都恰好被統計了一次!於是這樣算出來的答案就是正確的了。
什麼?你說求多邊形的交很難?那不是半平面交的板子嘛……

例題

給定一個n個點,m條邊的無向圖,每條邊都有一個從 1 1 n 1 n-1 編號的顏色。求它所有的生成樹,滿足樹中任意兩條邊顏色不同。
n 15 15 n\le 15,顏色數\le 15

解決方案

顯然每種顏色必須出現且僅出現一次。
考慮如果沒有顏色不同的限制,實際上這是一個裸的矩陣樹定理。但是這題有了限制,我們就考慮暴力列舉哪種顏色的邊沒有出現,然後對於剩下來的邊求一遍生成樹計數,於是就直接容斥就好了,複雜度 O ( 2 n ( n 1 ) 3 ) O(2^n(n-1)^3)

普通容斥原理的推廣

例題

給定平面上的n個矩形,如果一個區域被奇數個矩形覆蓋,那麼該區域為黑色,否則為白色。求所有被黑色格子覆蓋的矩形面積。( n 20 n\le 20

解決方案

資料量很小肯定可以考慮容斥。但是上面普通的容斥只能夠計算覆蓋的面積,而對於這種特殊情況就不能處理。我們可以考慮反推,也就是說從每個小矩形需要被計算的次數反推容斥係數。
不妨假定大小為 i i 的集合容斥係數為 f ( i ) f(i) 。則——
i = 1 k ( k i ) f ( i ) = [ k   m o d   2 = 1 ] \sum_{i=1}^k\binom kif(i)=[k~mod~2=1]
顯然這是一個二項式反演的形式,於是就可以推出來 f f 了(二項式反演連結
f ( k ) = i = 1 k ( 1 ) k i ( k i ) [ i   m o d   2 = 1 ] = ( 1 ) k 1 2 k 1 f(k)=\sum_{i=1}^k(-1)^{k-i}\binom ki·[i~mod~2=1]=(-1)^{k-1}·2^{k-1}
這裡用到了組合數奇數項求和等於偶數項求和的定理(當然資料量這麼小暴算也沒問題)。於是這道題直接就用容斥在 O ( 2 n ) O(2^n) 的時間內解決了。

例題

給定平面上的n個矩形,計算被且僅被一個矩形覆蓋的面積大小。

解決方案

套路是一樣的,一個塊恰好被一個矩形覆蓋則為1,否則為0.那麼:
i = 1 k ( k i ) f ( i ) = [ k = 1 ] f ( k ) = i = 1 k ( 1 ) k i ( k i ) [ i = 1 ] = ( 1 ) k 1 k \sum_{i=1}^k\binom kif(i)=[k=1],f(k)=\sum_{i=1}^k(-1)^{k-i}\binom ki[i=1]=(-1)^{k-1}k
於是容斥係數就算出來了,接下來直接容斥就行。