- 注:もちろん、この質問は2進数で列挙することもできますが、0 \ small0は必要ありません。0このバイナリ。
- トピック
- 質問:質問を参照してください。
- 解決策:
許容範囲と除外の原則:
要約:許容範囲と除外の原則は奇数プラス偶数マイナスです。
式ができたら、dfs \ small dfsD F Sは解決することができます。
変数の意味:
{pos:配列のpos位置をトラバースするopt:許容誤差の原理の記号(+1または-1)mul:pos位置の前に選択された数の積\ small \ begin {cases } \ pos:traverse配列のpos位置\\ \ opt:許容誤差の原理の符号(+1または-1)\\ \ mul:pos位置の前に選択された数値の積\\ \ end {ケース}⎩⎨⎧ p o s:通過カレンダーの数組の最初のP O Sのビットを o p t:受信撥元の根拠のシンボル数(+ 1 、または−1 ) m u l:最初のP O Sのビットの前部の選挙の数の乗算の積
各番号を左から右にトラバースします。この番号については、取得するかどうかを指定できます。
取られていない:トラバースされた位置に1を加えたものを除いて、残りは変更されません。
取る:許容誤差と排他原理の奇数プラス偶数減算の性質によって取得できるトラバース位置に1を追加します。もう1つの数値を取得する場合は、符号を変更する必要があるため、opt \ small opto p tプラスマイナス記号の場合、現在の数値にu [pos] \ small u [pos]を掛けます。U [ P O S ]。
許容範囲と除外の原則には少なくとも1つの数値が必要であり、その数値を取得しない場合はないため、pos \ smallposに移動するとp o sの場合、回答の寄与はu [pos] \ small u [pos]としてカウントする必要があります。u [ p o s ]の場合、(mul:posの前に選択された数の積)\ small(mul:posの前に選択された数の積)(m u l:上のP- O Sのビットの前の選挙の数の積和演算)、答えの寄与がある:M \ M小メートル对MUL * U [POS] \小さなMUL * U [POS]m u l∗U [ P O S ]は切り捨てされます。
並べ替えの剪定操作:数値の積がm \smallmより大きい場合に問題を見つけますmの場合、答えには寄与しないため、pos \ smallposに移動する場合p o sが境界を越えると、次の番号をトラバースできます。 - 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
//定义+命名空间
typedef long long ll;
typedef unsigned long long ull;
const int mod = 10007;
const ll INF = 1e18;
const int maxn = 1e6 + 10;
using namespace 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; }
void dfs(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]);
}
else return;
}
//主函数
int DoIdo() {
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;
return 0;
}
//分割线---------------------------------QWQ
/*
*/