제출 #598692

#제출 시각아이디문제언어결과실행 시간메모리
598692MKopchev던전 (IOI21_dungeons)C++17
100 / 100
5181 ms235056 KiB
#include "dungeons.h" #include<bits/stdc++.h> using namespace std; const int nmax=4e5+42,C=3000,SZ=24; int mem_n; vector<int> opponent_power,lose_gain,win_move,lose_move; long long gain_only_wins[nmax]; long long lowest_only_wins[nmax]; long long gain_large_win[nmax]; int win_move_large[nmax]; long long gain_large_lose[nmax]; int lose_move_large[nmax]; long long highest_only_losses[SZ][nmax]; long long gain_only_losses[SZ][nmax]; int move_only_losses[SZ][nmax]; void init(int n, std::vector<int> s, std::vector<int> p, std::vector<int> w, std::vector<int> l) { mem_n=n; opponent_power=s; lose_gain=p; win_move=w; lose_move=l; for(int i=n-1;i>=0;i--) { gain_only_wins[i]=opponent_power[i]+gain_only_wins[win_move[i]]; lowest_only_wins[i]=max(1LL*opponent_power[i],lowest_only_wins[win_move[i]]-opponent_power[i]); } for(int i=n-1;i>=0;i--) { gain_large_win[i]=opponent_power[i]; win_move_large[i]=win_move[i]; if(win_move[i]!=n&&opponent_power[win_move[i]]<C) { win_move_large[i]=win_move_large[win_move[i]]; gain_large_win[i]+=gain_large_win[win_move[i]]; } } for(int i=n-1;i>=0;i--) { gain_large_lose[i]=lose_gain[i]; lose_move_large[i]=lose_move[i]; if(lose_move[i]!=n&&opponent_power[lose_move[i]]<C) { lose_move_large[i]=win_move_large[lose_move[i]]; gain_large_lose[i]+=gain_large_win[lose_move[i]]; } } for(int i=0;i<n;i++) { highest_only_losses[0][i]=opponent_power[i]-1; gain_only_losses[0][i]=gain_large_lose[i]; move_only_losses[0][i]=lose_move_large[i]; } for(int step=1;step<SZ;step++) for(int i=0;i<n;i++) { highest_only_losses[step][i]=min(highest_only_losses[step-1][i],highest_only_losses[step-1][move_only_losses[step-1][i]]-gain_only_losses[step-1][i]); gain_only_losses[step][i]=gain_only_losses[step-1][i]+gain_only_losses[step-1][move_only_losses[step-1][i]]; move_only_losses[step][i]=move_only_losses[step-1][move_only_losses[step-1][i]]; } /* for(int i=0;i<n;i++) cout<<i<<" -> "<<win_move_large[i]<<" "<<gain_large_win[i]<<" "<<lose_move_large[i]<<" "<<gain_large_lose[i]<<endl; */ } long long simulate(int x, int z_) { long long z=z_; while(z<lowest_only_wins[x]&&z<C) { if(opponent_power[x]<=z) { z+=opponent_power[x]; x=win_move[x]; } else { z+=lose_gain[x]; x=lose_move[x]; } } if(z>=lowest_only_wins[x])return z+gain_only_wins[x]; while(z<lowest_only_wins[x]) { if(opponent_power[x]<=z) { z+=gain_large_win[x]; x=win_move_large[x]; } else { /* z+=gain_large_lose[x]; x=lose_move_large[x]; */ for(int j=SZ-1;j>=0;j--) if(z<=highest_only_losses[j][x]) { //cout<<"jump "<<z<<" "<<j<<" "<<x<<" "<<gain_only_losses[j][x]<<" "<<move_only_losses[j][x]<<endl; z+=gain_only_losses[j][x]; x=move_only_losses[j][x]; } } } z+=gain_only_wins[x]; return z; } /* static int n, q; static std::vector<int> s, p, z; static std::vector<int> w, l, x; static std::vector<long long> answer; int main() { assert(scanf("%d %d", &n, &q) == 2); s.resize(n); p.resize(n); w.resize(n); l.resize(n); x.resize(q); z.resize(q); answer.resize(q); for (int i = 0; i < n; i++) { assert(scanf("%d", &s[i]) == 1); } for (int i = 0; i < n; i++) { assert(scanf("%d", &p[i]) == 1); } for (int i = 0; i < n; i++) { assert(scanf("%d", &w[i]) == 1); } for (int i = 0; i < n; i++) { assert(scanf("%d", &l[i]) == 1); } init(n, s, p, w, l); for (int i = 0; i < q; i++) { assert(scanf("%d %d", &x[i], &z[i]) == 2); answer[i] = simulate(x[i], z[i]); } fclose(stdin); for (int i = 0; i < q; i++) { printf("%lld\n", answer[i]); } fclose(stdout); return 0; } */
#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...