总结:容斥原理就是奇加偶减。 有了公式就直接
d
f
s
\small dfs
dfs求解就可。 变量的含义:
{
p
o
s
:
遍
历
数
组
的
第
p
o
s
位
o
p
t
:
容
斥
原
理
的
符
号
(
+
1
或
−
1
)
m
u
l
:
第
p
o
s
位
之
前
所
选
的
数
的
乘
积
\small \begin{cases} \ pos:遍历数组的第pos位\\ \ opt:容斥原理的符号(+1或-1)\\ \ mul:第pos位之前所选的数的乘积\\ \end{cases}
⎩⎨⎧pos:遍历数组的第pos位opt:容斥原理的符号(+1或−1)mul:第pos位之前所选的数的乘积 从左往右遍历每个数,对于这个数来说,可以取,也可以不取。 不取:除了遍历的位置加一,其余不变。 取:遍历的位置加一,由容斥原理的奇加偶减的性质可以得到,多取一个数,它肯定变号,所以
o
p
t
\small opt
opt加负号,当前的数乘
u
[
p
o
s
]
\small u[pos]
u[pos]。 会发现容斥原理至少取一个数,没有不取数的情况,所以当遍历到
p
o
s
\small pos
pos时,答案的贡献必须算上取
u
[
p
o
s
]
\small u[pos]
u[pos]的情况,由于
(
m
u
l
:
第
p
o
s
位
之
前
所
选
的
数
的
乘
积
)
\small (mul:第pos位之前所选的数的乘积)
(mul:第pos位之前所选的数的乘积),对答案的贡献为:
m
\small m
m对
m
u
l
∗
u
[
p
o
s
]
\small mul*u[pos]
mul∗u[pos]下取整。 排序剪枝操作:发现题目,当数的乘积大于
m
\small m
m时,就对答案没贡献了,所以当遍历到
p
o
s
\small pos
pos已经越界时,后面的数就可以不用遍历了。
AC代码
//优化#pragma GCC optimize(2)//C#include<string.h>#include<stdio.h>#include<stdlib.h>#include<math.h>//C++#include<unordered_map>#include<algorithm>#include<iostream>#include<istream>#include<iomanip>#include<climits>#include<float.h>#include<cstdio>#include<string>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>//宏定义#define N 1010#define DoIdo main//#define scanf scanf_s#define it set<ll>::iterator#define TT template<class T>#define cint const int //定义+命名空间typedeflonglong ll;typedefunsignedlonglong ull;constint mod =10007;const ll INF =1e18;constint maxn =1e6+10;usingnamespace std;//全局变量
ll n, m;
ll u[25];
ll ans =0;//函数区
ll max(ll a, ll b){return a > b ? a : b;}
ll min(ll a, ll b){return a < b ? a : b;}
ll loop(ll n, ll p){return(n % p + p)% p;}voiddfs(ll pos, ll opt, ll mul){//如果遍历的数超过输入的数,则返回if(pos == n +1)return;//这就是u[pos] * mul <= m的变形//这样可以预防long long溢出if(u[pos]<= m / mul){//加一下对答案的贡献
ans += opt * m /(mul * u[pos]);//不取的情况dfs(pos +1, opt, mul);//取的情况dfs(pos +1,-opt, mul * u[pos]);}elsereturn;}//主函数intDoIdo(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
cin >> n >> m;for(int i =1; i <= n; i++){
cin >> u[i];}sort(u +1, u + n +1);dfs(1,1,1);
cout << ans << endl;return0;}//分割线---------------------------------QWQ/*
*/