HDU-1796 How many integers can you find

原题传送门:http://acm.hdu.edu.cn/showproblem.php?pid=1796

Sample Input
12 2
2 3
Sample Output
7

题目大意:给你两个整数n和m,m是一个整数集合的个数,我们所需要求的是1->n-1中有多少数可以被该整数集合某个元素整除。

解题思路:需要用到容斥定理。根据集合里的元素,遇奇则加,遇偶则减(其实就是羡慕别人一对对的)。遇奇则加中的奇意思是用到m中奇数个元素,同理,偶也是如此。具体看代码。

然后有一点需要注意,由于集合中的元素可能并不互质,所以可能会多加或多减一部分,所以我们需要用到lcm。其他就是容斥定理的模板了,其实我也刚学,模板可能很快就忘了。(⊙﹏⊙)b,还要排除掉0的干扰。

Code:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>

using namespace std;
typedef long long ll;
ll n;

ll gcd(ll a,ll b){//最大公约数 
	return b?gcd(b,a%b):a;
}

int main(){
	ll m,a[15],b[15];
	while(cin>>n>>m){
		int c=0;
		memset(a,0,sizeof(a));
		for(int i=1;i<=m;i++){
			cin>>a[i];
			if(a[i]!=0){//排除掉0 
				b[c++]=a[i];
			}
		}
		ll ans=0;
		for(int i=1;i<(1<<m);i++){
			ll cnt=0,sum=1;
			for(int j=0;j<m;j++){
				if(1&(i>>j)){
					cnt++;//cnt表示用到元素的个数 
					sum=sum*b[j]/gcd(sum,b[j]);//两个数相乘除以他们的最大公约数就是他们的最小公倍数 
				}
			}
			if(1&cnt){//遇奇则加 
				ans+=(n-1)/sum;
			}
			else {//遇偶则减 
				ans-=(n-1)/sum;
			}
		}
		cout<<ans<<endl;
	}
	
	return 0;
}
posted @ 2019-08-15 21:11  voids5  阅读(68)  评论(0编辑  收藏  举报