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示例
10Output示例
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
相关文章推荐
- 51Nod - 1284 2 3 5 7的倍数 容斥
- 51nod - 1284 2 3 5 7的倍数(容斥)
- 51nod 1284 2 3 5 7的倍数(容斥)
- 51nod 1284 2 3 5 7的倍数(容斥)
- 51nod-1284 2 3 5 7 倍数
- 51nod 1284《2 3 5 7的倍数》
- 【51Nod】1284 - 2 3 5 7的倍数(容斥原理 & 二进制优化)
- 51nod 1284 2 3 5 7的倍数
- 51nod-【1284 2 3 5 7的倍数】
- 51NOD 1284 2 3 5 7的倍数
- 51nod 1284【容斥】
- 51nod 1284 2 3 5 7的倍数(容斥定理)
- 51nod 1284 2 3 5 7的倍数
- 2 3 5 7的倍数 51Nod - 1284
- 每日一题(4)51nod 1284 2 3 5 7的倍数
- 51nod 1284 2 3 5 7的倍数
- 51nod 1284 2 3 5 7的倍数
- 51nod 1284 2 3 5 7的倍数
- 51Nod 1284 2 3 5 7的倍数
- 51Nod 1284 2 3 5 7的倍数 (容斥原理)