#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; int k; unsigned long long N; unsigned long long p[30]; unsigned long long BEST = 0; unsigned long long iter = 0; unsigned long long NEXTCHECK; int GENLIMIT = 6500000; unsigned long long RECLIMIT; int tab[1923000]; int cnt = 0; void generate(int pi, long long res) { tab[cnt++] = res; if (pi == k) return; while (true) { generate(pi+1, res); res *= p[pi]; if (res > GENLIMIT) return; } } inline void turbo(long long res) { int l = 0; int r = cnt; while (l < r) { int m = (l + r) / 2; unsigned long long mul = res * tab[m]; if (mul > N || mul / tab[m] != res) { r = m; continue; } if (mul > BEST) BEST = mul; l = m+1; } } void check(int pi, long long res) { iter++; //if ((iter & 16777215) == 0) { printf("."); fflush(stdout); } if ((iter & 1023) == 0) { unsigned long long x = NEXTCHECK; for (int i = k-1; i >= 0; i--) { while((x % p[i]) == 0) x /= p[i]; } if (x == 1) { printf("%llu\n", NEXTCHECK); //printf("found from top, iter=%llu\n", iter); exit(0); } NEXTCHECK--; } if (res > RECLIMIT) { turbo(res); return; } if (res > BEST) { BEST = res; /* printf("NEWBEST=%lld\n", BEST); */ } if (pi == k) return; if ((pi & 1) == 0) { // go from beginning int i = pi / 2; while (true) { check(pi+1, res); res *= p[i]; if (res > N) return; } } else { // go from end int i = k - pi / 2 - 1; while (true) { check(pi+1, res); res *= p[i]; if (res > N) return; } } } int main() { int i; scanf("%d %lld", &k, &N); for (i = 0; i < k; i++) { scanf("%lld", &p[i]); } sort(p, p+k); BEST = p[0]; NEXTCHECK = N; if (N < GENLIMIT) GENLIMIT = N; generate(0, 1); //printf("gencnt=%d\n", cnt); sort(tab, tab+cnt); RECLIMIT = (p[k-1] + 1) * (N / GENLIMIT); check(0, 1); printf("%llu\n", BEST); //printf("found from bottom, iter=%llu\n", iter); }
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 | #include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; int k; unsigned long long N; unsigned long long p[30]; unsigned long long BEST = 0; unsigned long long iter = 0; unsigned long long NEXTCHECK; int GENLIMIT = 6500000; unsigned long long RECLIMIT; int tab[1923000]; int cnt = 0; void generate(int pi, long long res) { tab[cnt++] = res; if (pi == k) return; while (true) { generate(pi+1, res); res *= p[pi]; if (res > GENLIMIT) return; } } inline void turbo(long long res) { int l = 0; int r = cnt; while (l < r) { int m = (l + r) / 2; unsigned long long mul = res * tab[m]; if (mul > N || mul / tab[m] != res) { r = m; continue; } if (mul > BEST) BEST = mul; l = m+1; } } void check(int pi, long long res) { iter++; //if ((iter & 16777215) == 0) { printf("."); fflush(stdout); } if ((iter & 1023) == 0) { unsigned long long x = NEXTCHECK; for (int i = k-1; i >= 0; i--) { while((x % p[i]) == 0) x /= p[i]; } if (x == 1) { printf("%llu\n", NEXTCHECK); //printf("found from top, iter=%llu\n", iter); exit(0); } NEXTCHECK--; } if (res > RECLIMIT) { turbo(res); return; } if (res > BEST) { BEST = res; /* printf("NEWBEST=%lld\n", BEST); */ } if (pi == k) return; if ((pi & 1) == 0) { // go from beginning int i = pi / 2; while (true) { check(pi+1, res); res *= p[i]; if (res > N) return; } } else { // go from end int i = k - pi / 2 - 1; while (true) { check(pi+1, res); res *= p[i]; if (res > N) return; } } } int main() { int i; scanf("%d %lld", &k, &N); for (i = 0; i < k; i++) { scanf("%lld", &p[i]); } sort(p, p+k); BEST = p[0]; NEXTCHECK = N; if (N < GENLIMIT) GENLIMIT = N; generate(0, 1); //printf("gencnt=%d\n", cnt); sort(tab, tab+cnt); RECLIMIT = (p[k-1] + 1) * (N / GENLIMIT); check(0, 1); printf("%llu\n", BEST); //printf("found from bottom, iter=%llu\n", iter); } |