容斥原理

容斥原理

容斥原理
蒟蒻打不来LaTeX;口头描述一下,大概就是:
设S1,S2,…Sn;为有限集合,|S|表示集合的大小;
所有集合的并集为
奇数个集合的交集减去偶数个集合的交集;

例题

给定一个整数 n 和 m 个不同的质数 p1,p2,…,pm。

请你求出 1∼n 中能被 p1,p2,…,pm 中的至少一个数整除的整数有多少个。

输入格式

第一行包含整数 n 和 m。

第二行包含 m 个质数。

输出格式

输出一个整数,表示满足条件的整数的个数。

数据范围

1≤m≤16,
1≤n,pi≤109

输入样例:

10 2
2 3

输出样例:

7

#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=20;
int n,m,p[N];
signed main()
{								
	scanf("%lld%lld",&n,&m);					
	for(int i=0;i<m;i++)scanf("%lld",&p[i]);//因为接下来要用到位运算和状态压缩所以从0开始
	int ass=0;
	for(int i=1;i< 1<<m;i++){//枚举所有状态状态压缩;
		int t=1,cnt=0;//	t表示暂时的积   cnt表示该状态之内的选取的数的个数
		for(int j=0;j<m;j++)//枚举每一位
			if(i>>j&1){
				cnt++;
				if(t*p[j] > n){
					t=-1;break;
				}
				t*=p[j];
			}
		if(t!=-1){
			if (cnt%2)ass+=n/t;//是奇数的集合则加上去
			else ass-=n/t;//是偶数的集合则减去
		}
	}
	printf("%lld",ass);
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值