Submission #1318209

#TimeUsernameProblemLanguageResultExecution timeMemory
1318209SmuggingSpunDungeons Game (IOI21_dungeons)C++20
100 / 100
3568 ms1659424 KiB
#include "dungeons.h" #include<bits/stdc++.h> using namespace std; typedef long long ll; template<class T>void minimize(T& a, T b){ if(a > b){ a = b; } } const int lim = 4e5 + 5; int n, subtask_id = -1; vector<int>s, p, w, l; namespace sub1{ int solve(int x, int z){ while(x < n){ if(z >= s[x]){ z += s[x]; x = w[x]; } else{ z += p[x]; x = l[x]; } } return z; } } struct Data{ int to; ll need, sum; Data(){} Data(int _to, ll _need, ll _sum) : to(_to), need(_need), sum(_sum) {} }; namespace sub2{ bool check_subtask(){ for(int i = 0; i < n; i++){ if(s[i] != p[i]){ return false; } } return true; } vector<Data>up[19]; void init(){ for(int i = 0; i < 19; i++){ up[i].resize(n + 1); up[i][n] = Data(n, 0, 0); } for(int i = 0; i < n; i++){ up[0][i] = Data(w[i], s[i], s[i]); } for(int i = 1; i < 19; i++){ for(int j = 0; j < n; j++){ up[i][j].to = up[i - 1][up[i - 1][j].to].to; up[i][j].need = max(up[i - 1][j].need, up[i - 1][up[i - 1][j].to].need - up[i - 1][j].sum); up[i][j].sum = up[i - 1][j].sum + up[i - 1][up[i - 1][j].to].sum; } } } ll solve(int x, ll z){ while(x < n){ for(int bit = 18; bit > -1; bit--){ if(up[bit][x].need <= z){ z += up[bit][x].sum; x = up[bit][x].to; } } if(x == n){ break; } z += p[x]; x = l[x]; } return z; } } const ll INF = 1e18; namespace sub34{ bool check_subtask(){ if(n > 50000){ return false; } unordered_map<int, bool>cnt; for(int& x : s){ cnt[x] = true; if(cnt.size() > 5){ return false; } } return true; } vector<ll>val_s; vector<pair<int, ll>>up[6][24]; int cnt_s; void init(){ for(int i = 0; i < n; i++){ if(find(val_s.begin(), val_s.end(), s[i]) == val_s.end()){ val_s.push_back(s[i]); } } sort(val_s.begin(), val_s.end()); val_s.push_back(INF); cnt_s = val_s.size(); for(int i = 0; i < cnt_s; i++){ for(int j = 0; j < 24; j++){ up[i][j].resize(n + 1); up[i][j][n] = make_pair(n, 0); } for(int j = 0; j < n; j++){ bool lose = s[j] >= val_s[i]; up[i][0][j] = make_pair(lose ? l[j] : w[j], lose ? p[j] : s[j]); } for(int j = 1; j < 24; j++){ for(int k = 0; k < n; k++){ up[i][j][k].first = up[i][j - 1][up[i][j - 1][k].first].first; up[i][j][k].second = up[i][j - 1][k].second + up[i][j - 1][up[i][j - 1][k].first].second; } } } } ll solve(int x, ll z){ for(int i = 0; i < cnt_s; i++){ for(int bit = 23; bit > -1; bit--){ ll nz = z + up[i][bit][x].second; if(nz < val_s[i]){ z = nz; x = up[i][bit][x].first; } } if(x == n){ break; } if(z < s[x]){ z += p[x]; x = l[x]; } else{ z += s[x]; x = w[x]; } } return z; } } namespace sub5{ vector<Data>up[25][25]; void init(){ for(int i = 0; i < 25; i++){ for(int j = 0; j < 25; j++){ up[i][j].resize(n + 1); up[i][j][n] = Data(n, INF, 0); } for(int k = 0; k < n; k++){ if(s[k] > (1 << i)){ up[i][0][k] = Data(l[k], s[k] - 1, p[k]); } else{ up[i][0][k] = Data(w[k], INF, s[k]); } } for(int j = 1; j < 25; j++){ for(int k = 0; k < n; k++){ up[i][j][k].to = up[i][j - 1][up[i][j - 1][k].to].to; up[i][j][k].need = min(up[i][j - 1][k].need, up[i][j - 1][up[i][j - 1][k].to].need - up[i][j - 1][k].sum); up[i][j][k].sum = up[i][j - 1][k].sum + up[i][j - 1][up[i][j - 1][k].to].sum; } } } } ll solve(int x, ll z){ for(int i = 0; i < 25; i++){ if(i == 24 || (1 << (i + 1)) > z){ for(int j = 24; j > -1; j--){ if(z <= up[i][j][x].need){ z += up[i][j][x].sum; x = up[i][j][x].to; } } if(x == n){ break; } if(z < s[x]){ z += p[x]; x = l[x]; } else{ z += s[x]; x = w[x]; } } } return z; } } namespace sub6{ const int lim = 4e5 + 1; Data up[25][7][lim]; void init(){ for(int i = 0; i < 25; i++){ for(int j = 0; j < 7; j++){ up[i][j][n] = Data(n, INF, 0); } for(int k = 0; k < n; k++){ if(s[k] > (1 << i)){ up[i][0][k] = Data(l[k], s[k] - 1, p[k]); } else{ up[i][0][k] = Data(w[k], INF, s[k]); } } for(int j = 1; j < 7; j++){ for(int k = 0; k < n; k++){ up[i][j][k] = Data(k, INF, 0); for(int t = 0; t < 5; t++){ minimize(up[i][j][k].need, up[i][j - 1][up[i][j][k].to].need - up[i][j][k].sum); up[i][j][k].sum += up[i][j - 1][up[i][j][k].to].sum; up[i][j][k].to = up[i][j - 1][up[i][j][k].to].to; } } } } } ll solve(int x, ll z){ for(int i = 0; i < 25; i++){ if(i == 24 || (1 << (i + 1)) > z){ for(int j = 6; j > -1; j--){ for(int t = 0; t < 130; t++){ if(z <= up[i][j][x].need){ z += up[i][j][x].sum; x = up[i][j][x].to; } else{ break; } } } if(x == n){ break; } if(z < s[x]){ z += p[x]; x = l[x]; } else{ z += s[x]; x = w[x]; } } } return z; } } void init(int _n, vector<int>_s, vector<int>_p, vector<int>_w, vector<int>_l){ n = _n; swap(s, _s); swap(p, _p); swap(w, _w); swap(l, _l); if(n <= 50000 && max(*max_element(s.begin(), s.end()), *max_element(p.begin(), p.end())) <= 10000){ subtask_id = 1; } else if(sub2::check_subtask()){ subtask_id = 2; sub2::init(); } else if(sub34::check_subtask()){ subtask_id = 4; sub34::init(); } else if(n <= 50000){ subtask_id = 5; sub5::init(); } else{ subtask_id = 6; sub6::init(); } } ll simulate(int x, int z){ if(subtask_id == 1){ return sub1::solve(x, z); } if(subtask_id == 2){ return sub2::solve(x, z); } if(subtask_id == 4){ return sub34::solve(x, z); } if(subtask_id == 5){ return sub5::solve(x, z); } return sub6::solve(x, z); }
#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...