容斥原理是解决这一类问题的:有 \(N\) 个集合 \(S_1,S_2,\dots,S_N\),求 \(|\bigcup \limits_{i=1}^{N}S_i|\)。
首先我们看这个 \(N=2\) 时的问题:
这时很明显答案为 \(|A|+|B|-|A\bigcap B|\) 。
以下是 \(N=3\) 时的样子:
此时答案显然为 \(|A|+|B|+|C|-|A\bigcap B|-|A\bigcap C|-|B\bigcap C|+|A\bigcap B\bigcap C|\)。
仔细观察这两个式子,我们就能发现,所有偶数个集合的交集前面都是减号,而奇数的前面的都是加号,也就是:
\[|\bigcup \limits_{i=1}^N S_i|=\sum \limits_{k=1}^N (-1)^{k-1} \sum \limits_{1\le i_1<i_2<\dots<i_k\le N}|\bigcap \limits_{j=1}^k S_{i_j}| \](具体证明在[这里](容斥原理_百度百科 (baidu.com)))
代码
for(int i = 1; i < (1 << n); ++i) {
ans += (__builtin_popcount(i) % 2 ? 1 : -1) * /* i 代表的集合之交 */;
}
标签:limits,sum,容斥,bigcup,bigcap,原理
From: https://www.cnblogs.com/yaosicheng124/p/18393670