您的位置:首页 > 其它

51NOD - 1284- 2 3 5 7的倍数【容斥详解+图解】

2017-11-22 15:22 246 查看

1284 2 3 5 7的倍数

给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数。 例如N = 10,只有1不是2 3 5 7的倍数。

Input

输入1个数N(1 <= N <= 10^18)。

Output

输出不是2 3 5 7的倍数的数共有多少。

Input示例

10

Output示例

1

题意: 注意范围略

分析: 之前做过几道容斥,没仔细总结过,顺便总结下趁着这个裸题 -

当两个数或三个的时候都好分析,这次是四个,也不难分析,如果多的话就不好分析了,先看四个的,我们形象的用集合的形式来表示2,3,5,7倍数



当一个数为n时,显然,所有2,3,5,7倍数的个数就是sum(甲,乙,丙,丁,Ⅰ,ⅡⅢ,Ⅳ,A,B,C,D,E),我们可以用n/2表示所有是2的倍数的个数也就相当于图中的sum(甲,Ⅰ,Ⅱ,A,B,C,E),当然n/3,n/5,n/7同理,我们发现如果把n/2,n/3,n/5,n/7加起来的话,答案是超的,其中红色为多算了一次,蓝色为多算了两次,紫色为多算了三次,我们现在想办法减掉。

我们可以这样减去一个n/(2*3),相当于sum(I,A,B,D,E),同理再减去n/(3*7)n/(7*5)n/(5*2)

我们如果都按照集合的方法结果正好缺一个E,如果我们再加上个E的话,算出来其实结果是不对的,算多了,为什么呢,细心地话就可以发现,其实不止这一种组合方式,也可以如下



所以我们会多算,那应该怎么算呢,才能保证正确的容斥呢,我们可以把每个交集都减去,这样就可避免了,也就是说在原来的基础上再减去 n/(2*7),n/(3*5),这两项,我们发现加了之后就会产生新的问题,答案缺少了A,B,C,D,我们发现n/(2*3*5) 代表sum(A,E),同理n/(2*3*7),n/(7*3*5),n/(2*7*5),我们可以发现如果加上之后正好多了个E,减去即可,而E = n/(2*3*5*7),从而答案得到了解决,代码很简单,主要是思想。

写出来后可以发现容斥的通式为



公式的推导可自行百度~

参考代码

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main() {
ll n;cin>>n;
ll sum = n/2 + n/3 + n/5 + n/7 - n/6 - n/10 - n/35 - n/21 - n/14 - n/15 + n/30 + n/42 + n/70 + n/105 - n/210;
cout<<n-sum<<endl;
}


如有错误或遗漏,请私聊下UP,thx
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: