#include <bits/stdc++.h>
// #pragma GCC optimize ("O3")
// #pragma GCC target ("sse4")
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i)
#define pb push_back
#define mp make_pair
#define st first
#define nd second
const int MOD = 1000000007;
int K;
int p[100];
int exps[100][100];
LL N;
LL result = 1;
void check(int* part1, int M1, int* part2, int M2) {
sort(part1, part1+M1);
sort(part2, part2+M2);
REP(i,K) {
int R = M2-1;
REP(j,M1) {
if (part1[j] * part2[0] > N / p[i]) break;
while (part1[j] * (LL)part2[R] > N / p[i]) --R; // DO SPRAWDZENIA!!!!!
result = max(result, part1[j] * (LL)part2[R] * p[i]);
}
}
}
struct State {
vector<int> exponents;
LL product;
const int limit;
};
bool next(State& state) {
FORD(i,K,0) {
if (state.product * p[i] <= state.limit) {
++state.exponents[i];
state.product *= p[i];
return true;
} else {
state.product /= exps[i][state.exponents[i]];
state.exponents[i] = 0;
}
}
return false;
}
const int PART_SIZE = 750000;
struct GenerateResult { int num; bool more; };
GenerateResult generate(State& state, int* out) {
REP(i, PART_SIZE) {
out[i] = state.product;
// printf("%d\n", out[i]);
if (!next(state)) return { i+1, false };
}
return { PART_SIZE, true };
}
int data[2 * PART_SIZE];
vector<State> parts;
int main() {
// ios_base::sync_with_stdio(0);
scanf("%d%lld", &K, &N);
REP(i,K) {
scanf("%d", &p[i]);
exps[i][0] = 1;
FOR(j,1,100) exps[i][j] = exps[i][j-1] * p[i];
}
int S = sqrt(N) + 5;
State state = { vector<int>(K, 0), 1, S };
parts.pb(state);
int generated_num = 0;
while (true) {
auto p = generate(state, data + generated_num);
generated_num += p.num;
if (!p.more) break;
if (parts.size() == 2) {
check(data, generated_num, data, generated_num);
generated_num = 0;
}
parts.pb(state);
}
check(data, generated_num, data, generated_num);
if (parts.size() > 2) {
REP(i,2) {
generate(parts[i], data);
FOR(j,2,parts.size()) {
int part_size = generate(state, data + PART_SIZE).num;
check(data, PART_SIZE, data + PART_SIZE, part_size);
}
}
}
printf("%lld\n", result);
}
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 116 117 118 119 120 121 | #include <bits/stdc++.h> // #pragma GCC optimize ("O3") // #pragma GCC target ("sse4") using namespace std; typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> PII; #define REP(i,n) for(int i=0;i<(n);++i) #define FOR(i,a,b) for (int i=(a); i<(b); ++i) #define FORD(i,a,b) for (int i=(a)-1; i>=(b); --i) #define pb push_back #define mp make_pair #define st first #define nd second const int MOD = 1000000007; int K; int p[100]; int exps[100][100]; LL N; LL result = 1; void check(int* part1, int M1, int* part2, int M2) { sort(part1, part1+M1); sort(part2, part2+M2); REP(i,K) { int R = M2-1; REP(j,M1) { if (part1[j] * part2[0] > N / p[i]) break; while (part1[j] * (LL)part2[R] > N / p[i]) --R; // DO SPRAWDZENIA!!!!! result = max(result, part1[j] * (LL)part2[R] * p[i]); } } } struct State { vector<int> exponents; LL product; const int limit; }; bool next(State& state) { FORD(i,K,0) { if (state.product * p[i] <= state.limit) { ++state.exponents[i]; state.product *= p[i]; return true; } else { state.product /= exps[i][state.exponents[i]]; state.exponents[i] = 0; } } return false; } const int PART_SIZE = 750000; struct GenerateResult { int num; bool more; }; GenerateResult generate(State& state, int* out) { REP(i, PART_SIZE) { out[i] = state.product; // printf("%d\n", out[i]); if (!next(state)) return { i+1, false }; } return { PART_SIZE, true }; } int data[2 * PART_SIZE]; vector<State> parts; int main() { // ios_base::sync_with_stdio(0); scanf("%d%lld", &K, &N); REP(i,K) { scanf("%d", &p[i]); exps[i][0] = 1; FOR(j,1,100) exps[i][j] = exps[i][j-1] * p[i]; } int S = sqrt(N) + 5; State state = { vector<int>(K, 0), 1, S }; parts.pb(state); int generated_num = 0; while (true) { auto p = generate(state, data + generated_num); generated_num += p.num; if (!p.more) break; if (parts.size() == 2) { check(data, generated_num, data, generated_num); generated_num = 0; } parts.pb(state); } check(data, generated_num, data, generated_num); if (parts.size() > 2) { REP(i,2) { generate(parts[i], data); FOR(j,2,parts.size()) { int part_size = generate(state, data + PART_SIZE).num; check(data, PART_SIZE, data + PART_SIZE, part_size); } } } printf("%lld\n", result); } |
English