#include <cstdio>
#include <algorithm>
#include <functional>
#include <climits>
typedef unsigned long ulong;
typedef unsigned long long ullong;
const int MAX_K = 30;
int k;
ullong N;
int p[MAX_K];
const int MAX_NUMS = 1511000;
const int MAX_BIGNUMS = 187000;
ullong num;
ulong nums[MAX_NUMS];
ullong bignum;
ullong bignums[MAX_BIGNUMS];
ullong mnum;
void gen(ullong val, int i) {
if (i == k-1) {
while (val <= (N+val-1)/val) {
if (val < ULONG_MAX) {
nums[num++] = val;
} else {
bignums[bignum++] = val;
}
val *= p[i];
}
if (val < ULONG_MAX) {
nums[num++] = val;
} else {
bignums[bignum++] = val;
}
return;
}
while (val <= (N+val-1)/val) {
gen(val, i+1);
val *= p[i];
}
if (val < ULONG_MAX) {
nums[num++] = val;
} else {
bignums[bignum++] = val;
}
}
ullong find(ullong target) {
if (target == mnum) {
return mnum;
}
ullong max = 0;
int start = std::distance(nums, std::lower_bound(nums, nums+num, target/mnum));
for (int i = std::max(0, start-4); i < num; ++i) {
if (nums[i] > target) {
return max;
}
auto it = std::upper_bound(nums, nums+num, target/nums[i]);
if (std::distance(nums, it) < i) {
break;
}
if (it != nums) {
--it;
max = std::max(max, ((ullong)nums[i])*(*it));
}
}
for (int i = 0; i < bignum; ++i) {
if (bignums[i] > target) {
return max;
}
auto it = std::upper_bound(nums, nums+num, target/bignums[i]);
if (it != nums) {
--it;
max = std::max(max, ((ullong)nums[i])*(*it));
}
}
return max;
}
ullong find_with_2(ullong target) {
ullong max = 0;
ullong mult = 1;
while (mult <= target) {
if (target&(~(mult-1)) < max) break;
max = std::max(max, mult*find(target/mult));
mult *= 2;
}
return max;
}
int main() {
scanf("%d%llu", &k, &N);
for (int i = 0; i < k; ++i) {
scanf("%d", &p[i]);
}
std::sort(p, p+k, std::greater<int>());
bool with_2 = false;
if (k > 1 && p[k-1] == 2) {
--k;
with_2 = true;
}
gen(1, 0);
std::sort(nums, nums+num);
std::sort(bignums, bignums+bignum);
mnum = nums[num-1];
if (with_2) {
printf("%llu\n", find_with_2(N));
} else {
printf("%llu\n", find(N));
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | #include <cstdio> #include <algorithm> #include <functional> #include <climits> typedef unsigned long ulong; typedef unsigned long long ullong; const int MAX_K = 30; int k; ullong N; int p[MAX_K]; const int MAX_NUMS = 1511000; const int MAX_BIGNUMS = 187000; ullong num; ulong nums[MAX_NUMS]; ullong bignum; ullong bignums[MAX_BIGNUMS]; ullong mnum; void gen(ullong val, int i) { if (i == k-1) { while (val <= (N+val-1)/val) { if (val < ULONG_MAX) { nums[num++] = val; } else { bignums[bignum++] = val; } val *= p[i]; } if (val < ULONG_MAX) { nums[num++] = val; } else { bignums[bignum++] = val; } return; } while (val <= (N+val-1)/val) { gen(val, i+1); val *= p[i]; } if (val < ULONG_MAX) { nums[num++] = val; } else { bignums[bignum++] = val; } } ullong find(ullong target) { if (target == mnum) { return mnum; } ullong max = 0; int start = std::distance(nums, std::lower_bound(nums, nums+num, target/mnum)); for (int i = std::max(0, start-4); i < num; ++i) { if (nums[i] > target) { return max; } auto it = std::upper_bound(nums, nums+num, target/nums[i]); if (std::distance(nums, it) < i) { break; } if (it != nums) { --it; max = std::max(max, ((ullong)nums[i])*(*it)); } } for (int i = 0; i < bignum; ++i) { if (bignums[i] > target) { return max; } auto it = std::upper_bound(nums, nums+num, target/bignums[i]); if (it != nums) { --it; max = std::max(max, ((ullong)nums[i])*(*it)); } } return max; } ullong find_with_2(ullong target) { ullong max = 0; ullong mult = 1; while (mult <= target) { if (target&(~(mult-1)) < max) break; max = std::max(max, mult*find(target/mult)); mult *= 2; } return max; } int main() { scanf("%d%llu", &k, &N); for (int i = 0; i < k; ++i) { scanf("%d", &p[i]); } std::sort(p, p+k, std::greater<int>()); bool with_2 = false; if (k > 1 && p[k-1] == 2) { --k; with_2 = true; } gen(1, 0); std::sort(nums, nums+num); std::sort(bignums, bignums+bignum); mnum = nums[num-1]; if (with_2) { printf("%llu\n", find_with_2(N)); } else { printf("%llu\n", find(N)); } } |
English