题目链接
题意
给定4个整数,求1-n中是这4个整数任意一个的倍数的数的个数。
分析
考察容斥原理。
如果被计数的事物有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)—来自百度百科。
同样,有N类物体,也有同样的公式
因此这道题的答案就是:
4个数的倍数的个数之和 n/a + n/b+n/c+n/d
减去每不同的两个数的最小公倍数是N的倍数个数之和
加上每不同的三个数的最小公倍数是N的倍数个数之和
减去4个数的最小公倍数是N的倍数个数之和
代码
#include <bits/stdc++.h>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
typedef long long ll;
ll gcd(ll a, ll b) {
if (b == 0)
return a;
return gcd(b , a % b);
}
ll lcm2(ll a, ll b) {
return a / gcd(a, b) * b;
}
ll lcm3(ll a, ll b, ll c) {
ll t = lcm2(a, b);
return lcm2(t, c);
}
ll lcm4(ll a, ll b, ll c, ll d) {
ll t = lcm3(a, b, c);
return lcm2(t, d);
}
int main(int argc, char** argv) {
ll a[4];
ll n;
cin >> n;
for (int i = 0; i < 4; i++)
cin >> a[i];
if (a[0] == 1 || a[1] == 1 || a[2] == 1 || a[3] == 1) {
cout << n;
return 0;
}
ll cnt = 0;
cnt += n / a[1] + n / a[2] + n / a[3] + n / a[0];
cnt -= n / lcm2(a[0], a[1]) + n / lcm2(a[0], a[2]) + n / lcm2(a[0], a[3]);
cnt -= n / lcm2(a[1], a[2]) + n / lcm2(a[1], a[3]) + n / lcm2(a[2], a[3]);
cnt += n / lcm3(a[0], a[1], a[2]) + n / lcm3(a[0], a[1], a[3]) + n / lcm3(a[0], a[3], a[2]) + n / lcm3(a[3], a[1], a[2]);
cnt -= n / lcm4(a[0], a[1], a[2], a[3]);
cout << cnt;
return 0;
}