제출 #504102

#제출 시각아이디문제언어결과실행 시간메모리
504102600MihneaArchery (IOI09_archery)C++17
39 / 100
2097 ms24812 KiB
#include <bits/stdc++.h> using namespace std; const int N = 2 * 200000 + 7; const int INF = (int) 1e9 + 7; int n; int r; int my_rank; int init_ord[N]; int ord[N]; int winner[N]; int loser[N]; vector<int> guys[N]; bool wannap; int thesol[N]; int simulate_step_for_get_brute() { for (int i = 0; i < n; i++) { if (ord[2 * i] < ord[2 * i + 1]) { winner[i] = ord[2 * i]; loser[i] = ord[2 * i + 1]; } else { winner[i] = ord[2 * i + 1]; loser[i] = ord[2 * i]; } guys[i].clear(); } guys[0].push_back(winner[0]); for (int i = 1; i < n; i++) { guys[i - 1].push_back(winner[i]); guys[i].push_back(loser[i]); } guys[n - 1].push_back(loser[0]); for (int i = 0; i < n; i++) { assert((int) guys[i].size() == 2); for (int it = 0; it < 2; it++) { ord[2 * i + it] = guys[i][it]; } } return (loser[0] == my_rank); } void print() { cout << " ----> "; for (int i = 0; i < 2 * n; i++) { cout << ord[i] + 1 << " "; } cout << "\n"; } int get_brute(int pos) { pos = 2 * pos; int sol = -1, ans = 0; assert(0 <= pos && pos < 2 * n); ord[pos] = my_rank; for (int i = 0; i < pos; i++) { ord[i] = init_ord[i]; } for (int i = pos + 1; i < 2 * n; i++) { ord[i] = init_ord[i - 1]; } if (wannap) print(); for (int j = 1; j <= r; j++) { ans += simulate_step_for_get_brute(); if (wannap) print(); } for (int i = 0; i < 2 * n; i++) { if (ord[i] == my_rank) { sol = i; } } if (wannap) cout << "= " << sol << "\n"; assert(sol != -1); return sol / 2 - ans * n; } int get(int x) { if (thesol[x] != INF) { return thesol[x]; } return thesol[x] = get_brute(x); } int rep(int x) { x %= n; if (x < 0) x += n; return x; } int mn = (int) 1e9; int best = -1; void upd(int i) { int x = get(i); int y = rep(x); if (y < mn) { mn = y; best = i; } else { if (y == mn) { best = max(best, i); } } } signed main() { ios::sync_with_stdio(0); cin.tie(0); //freopen ("input", "r", stdin); for (int i = 0; i < N; i++) { thesol[i] = INF; } wannap = 0; cin >> n >> r; r = 2 * n + r % n; cin >> my_rank; my_rank--; for (int i = 0; i < 2 * n - 1; i++) { cin >> init_ord[i]; init_ord[i]--; } upd(0); upd(n - 1); { int low = 0, high = n - 1; while (low <= high) { int mid = (low + high) / 2; upd(mid); if (get(mid) == get(0)) { low = mid + 1; } else { high = mid - 1; } } } int L = get(0), R = get(n - 1); for (int j = L; j <= R; j++) { if (j % n) { continue; } int low = 0, high = n - 1, the_value = INF; while (low <= high) { int mid = (low + high) / 2; upd(mid); if (get(mid) >= j) { high = mid - 1; the_value = mid; } else { low = mid + 1; } } low = the_value; high = n - 1; while (low <= high) { int mid = (low + high) / 2; upd(mid); if (get(mid) == get(the_value)) { low = mid + 1; } else { high = mid - 1; } } } cout << best + 1 << "\n"; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...