#include <cstdio> #include <vector> #include <algorithm> #include <functional> std::vector<int> primes; long long int currentBest = 1; long long int minModulo(long long int n) { long long int modulo = 100LL; for (int p : primes) { if (n % p < modulo) { modulo = n % p; } } return modulo; } long long int findFirstBestRec(long long int n) { long long int current = 1LL; for (int p : primes) { while (n % p == 0) { current *= p; n /= p; } } if (n > primes[0]) { n -= minModulo(n); current *= findFirstBestRec(n); } return current; } void initCurrentBest(long long int n) { long long int localBest; for (int i = 0; i < 1000; ++i) { n -= minModulo(n); localBest = findFirstBestRec(n); if (localBest > currentBest) { currentBest = localBest; if (currentBest >= n) { break; } } n--; } } long long int getBiggest(long long int n, unsigned int idx, long long int multiplier) { if (n == 0) { return 0; } if (n < primes[primes.size()-1]) { if (multiplier > currentBest) { currentBest = multiplier; } return 1; } if (n * multiplier < currentBest) { // no sense to continue return 1; } long long int best = 1; long long int current; for (int i = idx; i < primes.size(); ++i) { if ((n % primes[i]) == 0) { current = getBiggest(n / primes[i], i, multiplier * primes[i]) * primes[i]; if (current > best) { best = current; if (best == n) { break; } } } } for (int i = idx; i < primes.size(); ++i) { if ((n / primes[i]) * primes[i] > best) { current = getBiggest(n / primes[i], i, multiplier * primes[i]) * primes[i]; if (current > best) { best = current; if (best == n) { break; } } } } if (multiplier * best > currentBest) { currentBest = multiplier * best; } return best; } int main() { int k, p; long long int n; scanf("%d %lld", &k, &n); for (int i = 0; i < k; ++i) { scanf("%d", &p); primes.push_back(p); } std::sort(primes.begin(), primes.end(), std::greater<int>()); initCurrentBest(n); printf("%lld\n", getBiggest(n, 0, 1)); return 0; }
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 | #include <cstdio> #include <vector> #include <algorithm> #include <functional> std::vector<int> primes; long long int currentBest = 1; long long int minModulo(long long int n) { long long int modulo = 100LL; for (int p : primes) { if (n % p < modulo) { modulo = n % p; } } return modulo; } long long int findFirstBestRec(long long int n) { long long int current = 1LL; for (int p : primes) { while (n % p == 0) { current *= p; n /= p; } } if (n > primes[0]) { n -= minModulo(n); current *= findFirstBestRec(n); } return current; } void initCurrentBest(long long int n) { long long int localBest; for (int i = 0; i < 1000; ++i) { n -= minModulo(n); localBest = findFirstBestRec(n); if (localBest > currentBest) { currentBest = localBest; if (currentBest >= n) { break; } } n--; } } long long int getBiggest(long long int n, unsigned int idx, long long int multiplier) { if (n == 0) { return 0; } if (n < primes[primes.size()-1]) { if (multiplier > currentBest) { currentBest = multiplier; } return 1; } if (n * multiplier < currentBest) { // no sense to continue return 1; } long long int best = 1; long long int current; for (int i = idx; i < primes.size(); ++i) { if ((n % primes[i]) == 0) { current = getBiggest(n / primes[i], i, multiplier * primes[i]) * primes[i]; if (current > best) { best = current; if (best == n) { break; } } } } for (int i = idx; i < primes.size(); ++i) { if ((n / primes[i]) * primes[i] > best) { current = getBiggest(n / primes[i], i, multiplier * primes[i]) * primes[i]; if (current > best) { best = current; if (best == n) { break; } } } } if (multiplier * best > currentBest) { currentBest = multiplier * best; } return best; } int main() { int k, p; long long int n; scanf("%d %lld", &k, &n); for (int i = 0; i < k; ++i) { scanf("%d", &p); primes.push_back(p); } std::sort(primes.begin(), primes.end(), std::greater<int>()); initCurrentBest(n); printf("%lld\n", getBiggest(n, 0, 1)); return 0; } |