数学 _ 容斥原理
概述
引子:
如何计算这个图形的面积?
很显然:
\[|A\cup B\cup C|=|A|+|B|+|C|-|A\cap B|-|B\cap C|-|C\cap A|+|A\cap B\cap C|
\]
把上述问题推广到一般情况,就是我们熟知的容斥原理。
定义
集合的并
设 U 中元素有 m 种不同的属性,而第 i 种属性称为\(P_i\) ,拥有属性 \(P_i\) 的元素构成集合\(S_i\),那么,集合\(S_i\)的并为:
\(\bigcup_{i=1}^{m} S_i=S_1+S_2 + \ldots + S_m\)
\(\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,- (S_1 \bigcap S_2+S_1 \bigcap S_3+\ldots + S_{m-1} \bigcap S_m)\)
\(\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,+(S_1 \bigcap S_2 \bigcap S_3+\ldots + S_{m-2} \bigcap S_{m-1} \bigcap S_m)\)
\(\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,\,+ \ldots + (-1)^{m - 1}(\bigcap_{i=1}^{m}S)\)
复杂度:\(O(2^m)\)
集合的交
对于全集 U 下的 集合的并 可以使用容斥原理计算,而 集合的交 则用全集减去 补集的并集
求得
\[\bigcap_{i=1}^{n}S_i = U- \bigcup_{i=1}^n\overline{S_i}
\]
应用
区间[L,R]中与 k 互质的数的个数
模板题
复杂度: \(O(2^{fac[k]})\) 其 中 \(fac[k]\) 为 \(k\) 的质因子的种类数。
当fac[k]为10
时(时间复杂度才1e3),k就已经大于\(1e9\)了
结论就是1e18
的范围内,都可以算出来。
模板代码:
int a[N],num;
void getprime(int x){
num=0;
for(int i=2;i*i<=x;i++){
if( x%i==0){
a[num++]=i;
while(x%i==0)
x/=i;
}
}
if(x>1) a[num++]=x;
}
int qu(int r,int x){
getprime(x);
int ans=0;
for(int i=1;i<(1<<num);i++){
int k=0;
int mul=1;
for(int j=0;j<=num;j++){
if(i& (1<<j)){
k++;
mul*=a[j];
}
}
if(k%2) ans+=r/mul;
else ans-=r/mul;
}
if(ans<0) return 0;
if(r-ans<0) return 0;
return r - ans;
}
int que(int l,int r,int k){
return qu(r,k)-qu(l-1,k);
}