제출 #601193

#제출 시각아이디문제언어결과실행 시간메모리
601193Valaki2던전 (IOI21_dungeons)C++17
25 / 100
1317 ms2097152 KiB
#include "dungeons.h" #include <bits/stdc++.h> using namespace std; #define n N #define s S #define p P #define w W #define l L #define int long long #define pb push_back #define mp make_pair #define pii pair<int, int> #define fi first #define se second const int logn = 31; const int inf = 4e16 + 42; int n; vector<int> win_str, lose_str, win_pos, lose_pos; int k; vector<vector<vector<int> > > lift_str; vector<vector<vector<int> > > lift_pos; map<int, int> conv; vector<int> val; vector<int> cost; void solve() { for(int i = 0; i < n; i++) { conv[win_str[i]] = -1; } //conv[inf] = -1; k = (int) conv.size(); val.assign(k, 0); int val_idx = -1; vector<pii > v; for(const pii &p : conv) { val_idx++; v.pb(mp(p.fi, val_idx)); val[val_idx] = p.fi; } conv.clear(); for(const pii &p : v) { conv[p.fi] = p.se; } lift_str = lift_pos = vector<vector<vector<int> > > (k, vector<vector<int> > (1 + n, vector<int> (logn, 0))); int minimum_value = 0; // these are already won for(int cur_idx = 0; cur_idx < k; cur_idx++) { vector<vector<int> > &cur_lift_str = lift_str[cur_idx]; vector<vector<int> > &cur_lift_pos = lift_pos[cur_idx]; for(int i = 0; i <= n; i++) { if(win_str[i] <= minimum_value) { cur_lift_str[i][0] = win_str[i]; cur_lift_pos[i][0] = win_pos[i]; } else { cur_lift_str[i][0] = lose_str[i]; cur_lift_pos[i][0] = lose_pos[i]; } } for(int j = 1; j < logn; j++) { for(int i = 0; i <= n; i++) { cur_lift_str[i][j] = cur_lift_str[i][j - 1] + cur_lift_str[cur_lift_pos[i][j - 1]][j - 1]; cur_lift_pos[i][j] = cur_lift_pos[cur_lift_pos[i][j - 1]][j - 1]; } } minimum_value = val[cur_idx]; } cost.assign(1 + n, 0); for(int i = n - 1; i >= 0; i--) { cost[i] = win_str[i] + cost[win_pos[i]]; } } int query(int pos, int strength) { /*if(strength >= k) { return strength + cost[pos]; } for(int j = logn - 1; j >= 0; j--) { if(strength + lift_str[pos][j] < k) { strength += lift_str[pos][j]; pos = lift_pos[pos][j]; } } strength += lift_str[pos][0]; pos = lift_pos[pos][0]; return strength + cost[pos];*/ for(int cur_idx = 0; cur_idx < k; cur_idx++) { if(strength >= val[cur_idx]) { continue; } //cout << cur_idx << " - " << val[cur_idx] << ": " << pos << " " << strength << endl; for(int j = logn - 1; j >= 0; j--) { if(strength + lift_str[cur_idx][pos][j] < val[cur_idx]) { strength += lift_str[cur_idx][pos][j]; pos = lift_pos[cur_idx][pos][j]; } } //cout << cur_idx << " - " << val[cur_idx] << ": " << pos << " " << strength << endl; strength += lift_str[cur_idx][pos][0]; pos = lift_pos[cur_idx][pos][0]; } //cout << "last one: " << pos << " " << strength << endl; return strength + cost[pos]; } #undef n #undef s #undef p #undef w #undef l void init(signed n, vector<signed> s, vector<signed> p, vector<signed> w, vector<signed> l) { N = n; win_str = lose_str = win_pos = lose_pos = (vector<int> (n + 1, 0)); for(int i = 0; i < n; i++) { win_str[i] = s[i]; lose_str[i] = p[i]; win_pos[i] = w[i]; lose_pos[i] = l[i]; } win_str[n] = 0; lose_str[n] = 0; win_pos[n] = n; lose_pos[n] = n; solve(); } int simulate(signed x, signed z) { return query(x, z); } /* 3 1 2 6 9 3 1 2 2 2 3 1 0 1 0 1 */ /* 3 2 2 6 9 3 1 2 2 2 3 1 0 1 0 1 2 3 */
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...