题目描述
给定一个整数$n$和$m$个不同的质数$p1,p2,…,pm$。
请你求出$1~n$中能被$p1,p2,…,pm$中的至少一个数整除的整数有多少个。
数据范围
$1≤m≤16,
1≤n,
pi≤10^9
$
样例
输入样例:
10 2
2 3
输出样例:
7
做法:
至少一个数整除的整数可以用容斥原理求得
相关链接: 数学知识笔记
如何枚举集合两两间的并集呢?
可以使用dfs算法,暴力枚举每一个可能的排列。
又由于$C_n^0+C_n^1+C_n^2+…+C_n^n=2^n$所以,要运行$2^n-C_n^0$次,也就是$2^n-1$次
C++ 代码
#include<bits/stdc++.h>
using namespace std;
#define re register
#define Re register
#define ll long long
#define MAXN 30
int n,m;
ll ans,p[MAXN];
void dfs(int step,ll cnt,int opt){//step代表当前状态在数组中的位置,CNT代表目前的总乘积,opt代表目前是+还是-
if(cnt > n)return;//剪枝,忽略cnt大于0的情况
if(step)ans += n / cnt * opt;
opt = -opt;
for(Re int i = step + 1;i <= m;i++){
dfs(i,cnt * p[i],opt);
}
return;
}
int main() {
cin >> n >> m;
for(Re int i = 1;i <= m;i++){
cin >> p[i];
}
dfs(0,1,-1);
cout << ans << endl;
return 0;
}
能模拟样例嘛,本蒟蒻实在看不懂,球球大佬T~T
样例:10 2 2 3
首先,1~10中,5个数能被2整除,3个数能被3整除,1个数能被6整除
然而在dfs函数里,CNT为6时opt为-1,因而结果为5+3-1=7。
dfs函数其实就是枚举每一个组合。
file:///C:/Users/admin/AppData/Roaming/Tencent/TIM/Temp/0]AAWA%7D%60%7DV9%2508J_O@[%7B~GP.png
请问是什么意思,这个地址我看不到啊~
这个是你图片的本地地址,除你之外看不到的;想发图的话需要先把你的本地图片上传到图床再把图床的markdown地址粘过来
大于n吧?
i从step+1开始妙啊
i一定要从step+1开始吗
是的, 这样可以避免重复, 比如i j和j i是同一种情况
good
受益匪浅,谢谢~