bzoj2839 集合計數 容斥 組合

2022-05-07 10:12:11 字數 1532 閱讀 7146

2839: 集合計數time limit: 10 sec  memory limit: 128 mb

submit: 523  solved: 287

[submit][status][discuss] description

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

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

input

一行兩個整數n,k

output

一行為答案。

sample input

3 2

sample output

6 hint

【樣例說明】

假設原集合為

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

【資料說明】

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

選出k個重合元素的集合的方案數

首先是k個元素的選擇c(n,k)

再考慮其他元素不交的方案m

容斥: m=任意選集合的方案數-c(n-k,1)交集至少為1的方案+c(n-k,2)交集至少為2的方案...

ans=c(n,k)*sum(c(n-k,i)*(2^(2^(n-i-k))-1))  0<=i<=n-k

i=0是任意選的方案數

處理組合數可以用公式

其中涉及逆元,可以用遞推求逆元陣列

因為mod是乙個質數,也可以考慮費馬小定理

推薦blog

/*

選出k個重合元素的集合的方案數

首先是k個元素的選擇c(n,k)

再考慮其他元素不交的方案m

容斥: m=任意選集合的方案數-c(n-k,1)交集至少為1的方案+c(n-k,2)交集至少為2的方案...

ans=c(n,k)*sum(c(n-k,i)*(2^(2^(n-i-k))-1)) 0<=i<=n-k

i=0是任意選的方案數

處理組合數可以用公式

其中涉及逆元,可以用遞推求逆元陣列

因為mod是乙個質數,也可以考慮費馬小定理

推薦blog

*/#include

#include

#include

#include

#define ll long long

#define n 1000100

#define mod 1000000007

using

namespace

std;

int fac[n],n,k,now=2

;ll quick(

int a,int

b)

returnc;}

int c(int n,int

m)int

main()

ans=(ans*c(n+k,k))%mod;

ans<0?ans+=mod:1

; cout

}

BZOJ 2839 集合計數 廣義容斥

在乙個 n 個元素集合中的所有子集中選擇若干個,且交集大小為 k 的方案數.按照之前的套路,令 f k 表示欽定交集大小為 k 其餘隨便選的方案數.令 g k 表示交集恰好為 k 的方案數.則有 f k sum binomg k 反演得 g k sum 1 binomf i 而 f k binom2...

BZOJ2839 集合計數 容斥 組合

題目描述 乙個有n個元素的集合有2 n個不同子集 包含空集 現在要在這2 n個集合中取出若干集合 至少乙個 使得它們的交集的元素個數為k,求取法的方案數,答案模1e9 7。上式對嗎?顯然是不對的,以為它不僅統計了交集為k的而且統計了交集為k以上的。所以我們要用容斥。設g i 為交集大於等於i的方案數...

bzoj 2839 集合計數 容斥原理

因為要在n個裡面選k個,所以我們先列舉選的是哪 k 個,方案數為 c k 確定選哪k個之後就需要算出集合交集正為好這 k 個的方案數,考慮用容斥原理。我們還剩下 n k 個元素,交集至少為 k 的方案數為 2 相當於在僅有剩下 n k 個元素的集合裡隨便選,最後再往每個集合裡塞進這 k 個元素。然後...