1. 程式人生 > >【BZOJ2839】集合計數,容斥原理

【BZOJ2839】集合計數,容斥原理

傳送門(許可權題)
題面:
一個有N個元素的集合有2^N個不同子集(包含空集),現在要在這2^N個集合中取出若干集合(至少一個),使得
它們的交集的元素個數為K,求取法的方案數,答案模1000000007。

吐槽一下,不知道為什麼網上的題解都沒有超過10行的。。
應該是我太弱了吧,連這種題都不會做
初學容斥原理,把之前做過但並不理解的容斥原理題目又複習了一下,然後來做這道題
之前看到的一些例題都是求“至少為…”的答案,直接套容斥的最初形式就可以了,這道題是”恰好為…“的答案,然而我的一般化容斥形式用的並不熟練……
受3622的影響,寫了一個O(n2)的暴力,遞推恰好為i的方案數,然後Cin×(2

2ni1)減去i在大於i的方案數就可以了
f(i)=Cin×(22ni1)j=i+1nCijf(j)
然後我就想做字首和啥的來優化一下,但化了半天式子發現通過乘除係數和加減常數來算
換一種思路,聰哥讓我從方程組係數的角度看待容斥原理
容易發現這個式子Cin×(22ni1)對交集恰好為j的方案計算了Cij
我們先考慮i=k的情況,
i=kkk+1k+2k+3...nCkkCkk+1Ckk+2Ckk+3Ckn
此時交集大小為k的方案數恰好都被計算了一次,所以就考慮i
=k+1
,我們要把它的計算次數Ckk+1消去,同時它也會對下面的k+2,k+3…n產生影響,就是這個樣子
i=k+1kk+1k+2k+3...<