Solution : The principle of tolerance and exclusion :
Summary : The principle of tolerance and exclusion is odd plus even minus. Once you have the formula, just dfs \small dfsd f s can be solved. The meaning of the variables: {pos: traverse the pos position of the array opt: the symbol of the principle of tolerance (+1 or − 1) mul: the product of the number selected before the pos position \small \begin{cases} \ pos: traverse The pos position of the array \\ \ opt: the sign of the principle of tolerance (+1 or -1) \\ \ mul: the product of the number selected before the pos position \\ \end{cases}⎩⎨⎧pos:Passes calendar number of sets of the first P O S bitsopt:Receiving repellent original rationale of the symbol number ( + 1 or−1)m u l:The first P O S bit of the front of the election of the number of the multiplication product of Traverse each number from left to right, for this number, you can take it or not. Not taken : Except for the traversed position plus one, the rest remains unchanged. Take : add one to the traversed position, which can be obtained by the nature of the odd-plus-even-subtraction of the tolerance and exclusion principle. If one more number is taken, it must change sign, so opt \small opto p t plus minus sign, the current number is multiplied byu [pos] \small u[pos]u [ p o s ] . You will find that the principle of tolerance and exclusion takes at least one number, and there is no case of not taking the number, so when traversing topos \small posWhen p o s , the contribution of the answer must be counted asu [pos] \small u[pos]In the case of u [ p o s ] , because(mul: product of the number selected before pos) \small (mul: product of the number selected before pos)( m u l:On the p- O S bit of the front of the election of the number of multiply accumulate ) , the contribution of the answer is:m \ m Smallm对 m u l ∗ u [ p o s ] \small mul*u[pos] m u l∗u [ p o s ] is rounded down. Sorting pruning operation: find the problem, when the product of the number is greater thanm \small mWhen m , it has no contribution to the answer, so when traversing topos \small posWhen p o s has crossed the boundary, the following numbers can be traversed.
AC code
//优化#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/*
*/