#pragma GCC optimize("Ofast") #include #define LL long long int #define ULL unsigned LL #define LD long double #define FI first #define SE second #define PB push_back #define PF push_front #define MP make_pair #define V vector #define PQ priority_queue #define ALL(x) x.begin(), x.end() #define SZ(x) (int)(x).size() #define FORI(i, a, b) for(int i = a; i < b ; ++i) #define FORD(i, a, b) for(int i = a; i > b ; --i) using namespace std; using pii = pair; const double TIME_LIMIT = 4.2; const char DIRS[4] = {'L', 'D', 'R', 'U'}; const pii MOVES[4] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}}; inline LL sqr(LL x){ return x*x; } int calc_distance(pii p1, pii p2){ return sqrt(sqr(p1.first - p2.first) + sqr(p1.second - p2.second)); } int calc_dust_collection_factor(pii location, const V& p, const V& holes){ int min_dist = 1e9; for(auto hole: holes){ min_dist = min(min_dist, calc_distance(location, hole)); } assert(min_dist < SZ(p)); // cerr << location.first << ' ' << location.second << " gives " << p[min_dist] << " of dust having distance " << min_dist << endl; return p[min_dist]; } LL calc_score(string path, int x, int y, const V& p, V holes, int n, int s, int w, int z){ assert(SZ(path) <= s); int period = sqrt(s); LL score = calc_dust_collection_factor({x, y}, p, holes); set vsd = {{x, y}}; FORI(i,0,SZ(path)){ if ((i+1) % period == 0){ for(auto& hole: holes){ hole.first = ((LL)hole.first * w + z) % n + 1; hole.second = ((LL)hole.second * z + w) % n + 1; } vsd.clear(); } if (path[i] == 'L') y--; if (path[i] == 'R') y++; if (path[i] == 'U') x--; if (path[i] == 'D') x++; if (!vsd.count({x, y})){ score += calc_dust_collection_factor({x, y}, p, holes); vsd.insert({x, y}); } } return score; } string walk_sequentially(int x, int y, int n, int s){ int dx = x > n / 2 ? -1 : 1; int dy = y > n / 2 ? -1 : 1; string ans; while(s--){ if (dy == 1 && y < n){ ans += 'R'; y += dy; continue; } if (dy == -1 && y > 1){ ans += 'L'; y += dy; continue; } if (dx == 1 && x < n){ ans += 'D'; x += dx; dy = -dy; continue; } if (dx == -1 && x > 1){ ans += 'U'; x += dx; dy = -dy; continue; } } return ans; } string reach_point_and_walk_sequentially(pii from, pii to, int n, int s){ string ans; while(s && from.second > to.second){ ans += 'L'; from.second--; s--; } while(s && from.second < to.second){ ans += 'R'; from.second++; s--; } while(s && from.first > to.first){ ans += 'U'; from.first--; s--; } while(s && from.first < to.first){ ans += 'D'; from.first++; s--; } return ans + walk_sequentially(from.first, from.second, n, s); } pair walk_greedily(int x, int y, const V& p, V holes, int n, int s, int w, int z){ string ans; int period = sqrt(s); LL score = calc_dust_collection_factor({x, y}, p, holes); set vsd = {{x, y}}; FORI(i,0,s){ if ((i+1) % period == 0){ for(auto& hole: holes){ hole.first = ((LL)hole.first * w + z) % n + 1; hole.second = ((LL)hole.second * z + w) % n + 1; } vsd.clear(); } V> next_moves; FORI(j1,0,4){ int r = x + MOVES[j1].first; int c = y + MOVES[j1].second; if (min(r, c) < 1 || max(r, c) > n) continue; int add_score = vsd.count({r, c}) ? 0 : calc_dust_collection_factor({r, c}, p, holes); if ((i+2) % period == 0 || i + 1 == s) next_moves.push_back({add_score, {add_score, j1}}); else { FORI(j2,0,4){ if (MOVES[j1].first + MOVES[j2].first == 0 && MOVES[j1].second + MOVES[j2].second == 0) continue; r += MOVES[j2].first; c += MOVES[j2].second; if (1 <= min(r, c) && max(r, c) <= n) next_moves.push_back({add_score + (vsd.count({r, c}) ? 0 : calc_dust_collection_factor({r, c}, p, holes)), {add_score, j1}}); r -= MOVES[j2].first; c -= MOVES[j2].second; } } } sort(ALL(next_moves), greater>()); score += next_moves[0].second.first; int dir = next_moves[0].second.second; ans += DIRS[dir]; x += MOVES[dir].first; y += MOVES[dir].second; if (!vsd.count({x, y})){ vsd.insert({x, y}); } } return {ans, score}; } int main(){ ifstream cin("cleanUP.in"); ofstream cout("cleanUP.out"); mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); clock_t start_t = clock(); int n, k, s, w, z, x, y; cin >> n >> k >> s >> w >> z >> x >> y; int d = (n - 1) * sqrt(2) + 1; V p(d); FORI(i,0,d){ cin >> p[i]; } V holes(k); FORI(i,0,k){ cin >> holes[i].first >> holes[i].second; } auto ans = walk_sequentially(x, y, n, s); LL best_score = calc_score(ans, x, y, p, holes, n, s, w, z); auto greedy = walk_greedily(x, y, p, holes, n, s, w, z); if (greedy.second > best_score){ ans = greedy.first; best_score = greedy.second; } // for(auto corner: {MP(1,1), MP(1,n), MP(n,1), MP(n,n)}){ // auto cur = reach_point_and_walk_sequentially({x, y}, corner, n, s); // LL score = calc_score(cur, x, y, p, holes, n, s, w, z); //// cerr << cur << ' ' << score << endl; // if (score > best_score){ // ans = cur; // best_score = score; // } // } while((double)(clock() - start_t) / CLOCKS_PER_SEC < TIME_LIMIT){ pii target = {uniform_int_distribution(1, n)(rng), uniform_int_distribution(1, n)(rng)}; auto cur = reach_point_and_walk_sequentially({x, y}, target, n, s); LL score = calc_score(cur, x, y, p, holes, n, s, w, z); // cerr << target.first << ' ' << target.second << ' ' << cur << ' ' << score << endl; if (score > best_score){ ans = cur; best_score = score; } } cout << ans; // cerr << best_score << endl; return 0; }