对容斥原理的描述:(直接百度来的)
如果被计数的事物有A、B、C三类,那么,A类和B类和C类元素个数总和= A类元素个数 + B类元素个数 + C类元素个数 - 既是A类又是B类的元素个数 - 既是A类又是C类的元素个数 - 既是B类又是C类的元素个数 + 既是A类又是B类而且是C类的元素个数。(A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C)
容斥原理的基本思想:
先不考虑重叠的情况,把包含于某内容中的所有对象的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗漏又无重复。
集合表示公式:
两个集合的容斥关系公式:A∪B = A+B - A∩B
三个集合的容斥关系公式:A∪B∪C = A+B+C - A∩B - A∩C - B∩C + A∩B∩C
四个集合的容斥关系公式:A∪B∪C∪D = A+B+C+D - AB - AC - AD - BC - BD - CD + ABC+ABD+ACD+BCD - ABCD
由此看来,奇加偶减(奇数个集合相加,偶数个集合相减)
相关例题:
题目链接:https://www.51nod.com/Challenge/Problem.html#!#problemId=1284
解析:要求有多少个不是2的倍数&&不是3的倍数&&不是5的倍数&&不是7的倍数,等价为求n -(是2的倍数||是3的倍数||是5的倍数||是7的倍数)。
#include<stdio.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
ll n, num=0; //num是1~n中2 3 5 7倍数的总和
ll a,b,c,d,ab,ac,ad,bc,bd,cd,abc,abd,acd,bcd,abcd;
while(cin >> n)
{
a = n/2;
b = n/3;
c = n/5;
d = n/7;
ab = n/6;
ac = n/10;
ad = n/14;
bc = n/15;
bd = n/21;
cd = n/35;
abc = n/30;
abd = n/42;
acd = n/70;
bcd = n/105;
abcd = n/210;
num = a+b+c+d-ab-ac-ad-bc-bd-cd+abc+abd+acd+bcd-abcd;
cout << n-num << endl;
}
return 0;
}