Submission #1131451

#TimeUsernameProblemLanguageResultExecution timeMemory
1131451huutuanEscape Route 2 (JOI24_escape2)C++20
100 / 100
2460 ms346432 KiB
#include<bits/stdc++.h> using namespace std; using ll=long long; #ifdef sus const int N=21, LG=5, S=4; #else const int N=1e5+10, LG=17, S=700; #endif int rjump[LG][N], pos[N], lcost[LG][N]; ll rcost[LG][N], ljump[LG][N]; int jump[N/S+10][N]; ll cost[N/S+10][N], mem[N][N/S+10]; int nxt[N]; vector<pair<int, int>> v; int n, t, q; vector<pair<int, int>> edge[N]; ll get_rcost(int l, int r, int idl){ int d=r-l; int cur=idl; ll ans=0; for (int k=0; k<LG; ++k) if (d>>k&1){ ans+=rcost[k][cur]; cur=rjump[k][cur]; } int j=v[cur].second; return ans+edge[r][j].second-edge[r][j].first; } ll get_lcost(int l, int r, int idr){ int d=r-l; int cur=idr; ll ans=0; for (int k=0; k<LG; ++k) if (d>>k&1){ ans+=lcost[k][cur]; cur=ljump[k][cur]; } int j=v[cur].second; return ans+edge[l][j].second-edge[l][j].first; } ll get_cost(int l, int r, int idl){ int d=r-l; int cur=jump[d][idl]; int j=v[cur].second; return cost[d][idl]+edge[r][j].second-edge[r][j].first; } int32_t main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> t; for (int i=1; i<n; ++i){ int m; cin >> m; vector<pair<int, int>> tmp(m); for (auto &j:tmp) cin >> j.first >> j.second; sort(tmp.begin(), tmp.end(), [&](pair<int, int> x, pair<int, int> y){ return make_pair(x.first, -x.second)<make_pair(y.first, -y.second); }); for (auto &j:tmp){ while (edge[i].size() && edge[i].back().second>=j.second) edge[i].pop_back(); edge[i].push_back(j); } pos[i]=v.size(); for (int j=0; j<(int)edge[i].size(); ++j) v.emplace_back(i, j); } for (int id=0; id<(int)v.size(); ++id){ jump[0][id]=id; cost[0][id]=0; } for (int id=0; id<(int)v.size(); ++id){ int i=v[id].first, j=v[id].second; if (i==n-1) break; int i2=i+1; int j2=lower_bound(edge[i2].begin(), edge[i2].end(), make_pair(edge[i][j].second, -1))-edge[i2].begin(); j2%=(int)edge[i2].size(); rcost[0][id]=edge[i2][j2].first>=edge[i][j].second?edge[i2][j2].first-edge[i][j].first:edge[i2][j2].first-edge[i][j].first+t; rjump[0][id]=pos[i2]+j2; jump[1][id]=rjump[0][id]; cost[1][id]=rcost[0][id]; } for (int k=2; k<N/S+10; ++k){ for (int id=0; id<(int)v.size(); ++id){ if (v[id].first+k>n-1) break; jump[k][id]=jump[1][jump[k-1][id]]; cost[k][id]=cost[k-1][id]+cost[1][jump[k-1][id]]; } } for (int k=1; k<LG; ++k){ for (int id=0; id<(int)v.size(); ++id){ if (v[id].first+(1<<k)>n-1) break; rjump[k][id]=rjump[k-1][rjump[k-1][id]]; rcost[k][id]=rcost[k-1][id]+rcost[k-1][rjump[k-1][id]]; } } for (int id=(int)v.size()-1; id>=0; --id){ int i=v[id].first, j=v[id].second; if (i==1) break; int i2=i-1; int j2=lower_bound(edge[i2].begin(), edge[i2].end(), make_pair(-1, edge[i][j].first+1), [&](pair<int, int> x, pair<int, int> y){ return make_pair(x.second, x.first)<make_pair(y.second, y.first); })-edge[i2].begin(); j2=(j2+(int)edge[i2].size()-1)%(int)edge[i2].size(); lcost[0][id]=edge[i2][j2].second<=edge[i][j].first?edge[i][j].second-edge[i2][j2].second:edge[i][j].second-edge[i2][j2].second+t; ljump[0][id]=pos[i2]+j2; } for (int k=1; k<LG; ++k){ for (int id=(int)v.size()-1; id>=0; --id){ if (v[id].first-(1<<k)<1) break; ljump[k][id]=ljump[k-1][ljump[k-1][id]]; lcost[k][id]=lcost[k-1][id]+lcost[k-1][ljump[k-1][id]]; } } nxt[n]=n; for (int i=n-1; i>=1; --i){ if ((int)edge[i].size()<S) nxt[i]=i; else nxt[i]=nxt[i+1]; } memset(mem, -1, sizeof mem); cin >> q; while (q--){ int l, r; cin >> l >> r; --r; ll ans=1e18; if (nxt[l]<=r){ int i=nxt[l]; for (int j=pos[i]; j<pos[i]+(int)edge[i].size(); ++j) ans=min(ans, get_lcost(l, i, j)+get_rcost(i, r, j)-edge[i][j-pos[i]].second+edge[i][j-pos[i]].first); }else{ int d=r-l; if (mem[l][d]!=-1) ans=mem[l][d]; else{ for (int i=pos[l]; i<pos[l]+(int)edge[l].size(); ++i) ans=min(ans, get_cost(l, r, i)); mem[l][d]=ans; } } cout << ans << '\n'; } 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...