#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)); } } |