#include #pragma GCC optimize("O3") using namespace std; typedef long long ll; const int N = 1e5 + 3; const int MAX = 4e6 + 3; const ll INF = 1e18; const ll INF2 = 2e14; const ll INF3 = 1e14; int n, m, a, b, p[N], idx[N]; set points; int ans[N]; bool vis[N]; clock_t timer = clock(); mt19937 mt(234); ll get_dist(int i, int j){ return (ll)abs(p[i] - p[j]) * a + (ll)abs(idx[i] - idx[j]) * b; } bool check(ll mid){ points.clear(); for(int i = 1; i <= n; ++i) points.insert(i); int idx_ans = 0; ans[idx_ans] = 0; while(idx_ans >= 0){ ll best_dist = INF; int best_idx = -1; auto up_it = points.upper_bound(ans[idx_ans]); auto it = up_it; while(it != points.end()){ auto k = *it; if(best_dist <= (ll)(k - idx[ans[idx_ans]]) * b) break; ll curr_dist = (ll)(k - idx[ans[idx_ans]]) * b + (ll)abs(p[k] - p[ans[idx_ans]]) * a; if(curr_dist < best_dist){ best_dist = curr_dist; best_idx = k; } ++it; } it = up_it; while(it != points.begin()){ --it; int k = *it; if(best_dist <= (ll)(idx[ans[idx_ans]] - k) * b) break; ll curr_dist = (ll)(idx[ans[idx_ans]] - k) * b + (ll)abs(p[k] - p[ans[idx_ans]]) * a; if(curr_dist < best_dist){ best_dist = curr_dist; best_idx = k; } } if(best_idx == -1 || best_dist > mid){ idx_ans--; continue; } points.erase(best_idx); ans[++idx_ans] = best_idx; if(idx_ans == m) return true; } return false; } void solve_small(){ ll l = 0, r = INF2; while(l != r){ //cout << l << " " << r << endl; ll mid = (l + r) >> 1; if(check(mid)) r = mid; else l = mid + 1; } check(l); } void solve_big(){ if(check(get_dist(0, 1))) return; check(INF2); } bool time_left(){ return ((float)clock() - (float)timer) / (float)CLOCKS_PER_SEC <= 4.7; } bool time_left_2(){ return ((float)clock() - (float)timer / (float)CLOCKS_PER_SEC) <= 2; } void improve_small(){ for(int i = 1; i <= m - 1 && time_left(); ++i){ for(int j = 1; j <= n && time_left(); ++j){ if(vis[j]) continue; for(int k = 1; k <= n && time_left(); ++k){ if(vis[k] || k == j) continue; ll change = 0; change -= get_dist(ans[i - 1], ans[i]); change -= get_dist(ans[i], ans[i + 1]); if(i + 1 != m) change -= get_dist(ans[i + 1], ans[i + 2]); change += get_dist(ans[i - 1], j); change += get_dist(j, k); if(i + 1 != m) change += get_dist(k, ans[i + 2]); if(change < 0){ vis[ans[i]] = false; vis[ans[i + 1]] = false; ans[i] = j; ans[i + 1] = k; vis[j] = true; vis[k] = true; } } } } for(int i = 1; i <= m && time_left(); ++i){ for(int j = 1; j <= n && time_left(); ++j){ if(vis[j]) continue; ll change = 0; change -= get_dist(ans[i], ans[i - 1]); if(i != m) change -= get_dist(ans[i], ans[i + 1]); change += get_dist(j, ans[i - 1]); if(i != m) change += get_dist(j, ans[i + 1]); if(change < 0){ vis[ans[i]] = false; ans[i] = j; vis[j] = true; } } } for(int diff = 1; diff <= m - 1 && time_left(); ++diff){ for(int l = 1; l <= m - diff && time_left(); ++l){ int r = l + diff; ll curr = 0; curr += get_dist(ans[l], ans[l - 1]); if(r != m) curr += get_dist(ans[r], ans[r + 1]); ll nxt = 0; nxt += get_dist(ans[r], ans[l - 1]); if(r != m) nxt += get_dist(ans[l], ans[r + 1]); if(nxt < curr) reverse(ans + l, ans + r + 1); } } } void improve_big(){ for(int diff = 1; diff <= m - 1 && time_left(); ++diff){ for(int l = 1; l <= m - diff && time_left(); ++l){ int r = l + diff; ll curr = 0; curr += get_dist(ans[l], ans[l - 1]); if(r != m) curr += get_dist(ans[r], ans[r + 1]); ll nxt = 0; nxt += get_dist(ans[r], ans[l - 1]); if(r != m) nxt += get_dist(ans[l], ans[r + 1]); if(nxt < curr) reverse(ans + l, ans + r + 1); } } if(!time_left()) return; for(int i = 1; i <= m && time_left(); ++i){ for(int j = 1; j <= n && time_left(); ++j){ if(vis[j]) continue; ll change = 0; change -= get_dist(ans[i], ans[i - 1]); if(i != m) change -= get_dist(ans[i], ans[i + 1]); change += get_dist(j, ans[i - 1]); if(i != m) change += get_dist(j, ans[i + 1]); if(change < 0){ vis[ans[i]] = false; ans[i] = j; vis[j] = true; } } } } int main(){ ios::sync_with_stdio(false); cin.tie(NULL); freopen("cheating.in", "r", stdin); freopen("cheating.out", "w", stdout); cin >> n >> m >> a >> b; for(int i = 1; i <= n; ++i){ cin >> p[i]; idx[i] = i; } p[0] = 0; idx[0] = 1; if(n <= 2000) solve_small(); else solve_big(); fill(vis, vis + n + 1, false); for(int i = 1; i <= m; ++i) vis[ans[i]] = true; if(n <= 200) while(time_left()) improve_small(); else while(time_left()) improve_big(); for(int i = 1; i <= m; ++i) cout << ans[i] << "\n"; }