容斥原理:
有条件$S_1…S_n$,有如下公式:
$S_1US_2US_3=S_1+S_2+S_3-S_1∩S_2-S_1∩S_3-S_2∩S_3+S_1∩S_2∩S_3$
$2^{n}-1=C_n^1-C_n^2+C_n^3…(-1)^kC_n^n$(可将它类比成每个数选或不选)
一共有$2^{n}-1$个状态
对每一种状态求出 累乘的结果t,和这种状态选择的数的个数s
n/t用于求出 t的倍数1~n中会出现几次,s为奇数加上,s为偶数减去
import java.util.Scanner;
public class Main {
static int N = 20;
static int p[] = new int[N];
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
for(int i = 0 ; i < m ; i ++) p[i] = scanner.nextInt();
int res = 0;
for(int i = 1; i < 1<<m; i ++) {//枚举每一种方案
long t = 1,s = 0;//s用来记录这种方案,选择的数的个数,从而判断应该加还是减;t存累乘的结果
for(int j = 0; j < m ; j ++) {
if((i>>j&1)==1) {
if(t*p[j]>n) {//这里要加long 否则会溢出
t = -1;
break;
}
t *= p[j];
s++;
}//为这种方案求出一个总乘积t
}
if(t!=-1) {
if(s%2==1) res += n/t;//奇数个数,说明要加
else res -= n/t;//偶数个数,说明要减
}
}
System.out.println(res);
}
}
很简洁, 一看就突然明白了, 感谢感谢 ~
大佬,我想问一下,使用二进制 是要将每一位和不同质因子一一对应吗?分别代表质因子 分别为1个、2个…m个的情况?
是的,二进制的每一位代表 这些质数选还是不选, 011,就代表选择了第二个质数,第三个质数
(o´ω`o)ノ明白了