BZOJ2839 集合計數

2022-08-13 15:03:20 字數 1285 閱讀 1501

乙個有n個元素的集合有2n個不同子集(包含空集),現在要在這2n個集合中取出若干集合(至少乙個),使得

它們的交集的元素個數為k,求取法的方案數,答案模1000000007。(是質數喔~)

一行兩個整數n,k

一行為答案。

3 2

【樣例說明】

假設原集合為

則滿足條件的方案為:,,,,,

資料說明:對於100%的資料,1≤n≤1000000;0≤k≤n;

我竟然還能寫出容斥題來

元素的交集恰好是k不好計算

那麼我們就去考慮容斥

設\(f[i]\)表示有至少i個相交元素的方案數

那麼\(f[i] = (-1)^*c(n , i)*(2^}-1)\)

然後發現這樣不對

因為每種有i個相交元素的方案對\(f[k]\)的貢獻其實是\(c(i,k)\)

所以我們要把容斥係數修改成\((-1)^ * c(i , k)\)

讓\(f[i] = (-1)^*c(i,k)*c(n , i)*(2^}-1)\)

然後注意指數不能對\(1e9+7\)取膜!這玩意兒坑死我了

upd : 也可以用二項式反演做不過是一樣的

設\(g(i)\)表示至少有\(i\)個相交元素的方案數

\(f(i)\)表示恰好有\(i\)個元素的方案數

那麼顯然\(g(i)\)很好求,就是\(g(i)=\sum_^}-1)}\)

然後\(g(i)=\sum_^\)

所以我們可以對\(g(i)\)反演得\(f(i)=\sum_^*c(j,i)*g(j)}\)

#include#include# define int long long

const int m = 1000005 ;

const int mod = 1e9 + 7 ;

using namespace std ;

int n , k , ans , fac[m] ;

inline int fpw(int base , int k)

return temp ;

}inline int inv(int x)

inline int c(int n , int m)

# undef int

int main()

printf("%lld\n",ans) ;

return 0 ;

}

bzoj 2839 集合計數

題意 乙個有n個元素的集合有2 n2 n 2n個不同子集 包含空集 現在要在這2 n2 n 2n個集合中取出若干集合 至少乙個 使得它們的交集的元素個數為k,求取法的方案數,答案模1000000007 題解 好題。一開始覺得應該很簡單,然而很快就證明了我很天真。設f k cn k i 12n kc2...

bzoj2839 集合計數

bzoj許可權題 離線題庫 首先,還是按照這類題目的套路分析 設函式 g x 表示交集至少大小為 x 的方案數 那麼先組合數算選取 x 個數的方法,再對剩下的 n x 個數算集合的集合 也就是集族咯 個數,可以得到 g x 的表示式 g x binom 2 1 那麼我們只要找到乙個容斥函式 f i ...

bzoj2839 集合計數

傳送門 分析 咕咕咕我的做法和這個部落格幾乎相同 只是我在處理 2 1 的時候是先處理前面的再處理後面的 所以前面的 2 我們只需要從 i n 開始迴圈,每次平方即可 include include include include include include include include in...