Submission #489984

#TimeUsernameProblemLanguageResultExecution timeMemory
489984blueTreatment Project (JOI20_treatment)C++17
35 / 100
184 ms123868 KiB
#include <iostream> #include <algorithm> #include <vector> #include <deque> #include <set> using namespace std; using ll = long long; using pll = pair<ll, ll>; using vpll = vector<pll>; using vi = vector<int>; using vll = vector<ll>; struct project { ll T; ll L; ll R; ll C; int I; }; vector<project> P; const int maxM = 100'000; vi query_ans; vi visited(maxM, 0); const ll INF = 1'000'000'000'000'000'000LL; vll dp(maxM, INF); struct pos { int i; }; bool operator < (pos A, pos B) { if(dp[A.i] == dp[B.i]) return A.i < B.i; else return dp[A.i] < dp[B.i]; } struct segtree { int l; int r; deque<pair<int, int>> v; segtree* left = NULL; segtree* right = NULL; segtree() { ; } segtree(int L, int R) { l = L; r = R; if(l == r) return; int m = (l+r)/2; left = new segtree(l, m); right = new segtree(m+1, r); } void add(int I, ll Pr, ll val) { v.push_back({Pr, val}); if(l != r) { if(I <= (l+r)/2) left->add(I, Pr, val); else right->add(I, Pr, val); } } void get(int L, int R, ll mxv) { if(R < l || r < L) return; else if(L <= l && r <= R) { while(1) { if(v.empty()) break; if(v[0].second > mxv) break; if(!visited[v[0].first]) { query_ans.push_back(v[0].first); visited[v[0].first] = 1; } v.pop_front(); } } else { left->get(L, R, mxv); right->get(L, R, mxv); } } }; int main() { int N, M; cin >> N >> M; M = min(M, 40000); P = vector<project>(M); for(int i = 0; i < M; i++) cin >> P[i].T >> P[i].L >> P[i].R >> P[i].C; sort(P.begin(), P.end(), [] (project x, project y) { return x.T < y.T; }); for(int i = 0; i < M; i++) P[i].I = i; segtree U(0, M-1), D(0, M-1); sort(P.begin(), P.end(), [] (project x, project y) { return x.L + x.T <= y.L + y.T; }); for(int i = 0; i < M; i++) U.add(P[i].I, P[i].I, P[i].L + P[i].T); sort(P.begin(), P.end(), [] (project x, project y) { return x.L - x.T < y.L - y.T; }); for(int i = 0; i < M; i++) D.add(P[i].I, P[i].I, P[i].L - P[i].T); sort(P.begin(), P.end(), [] (project x, project y) { return x.I < y.I; }); for(int i = 0; i < M; i++) { if(P[i].L == 1) { dp[i] = P[i].C; visited[i] = 1; } } set<pos> tbv; for(int i = 0; i < M; i++) tbv.insert(pos{i}); while(!tbv.empty()) { int u = tbv.begin()->i; tbv.erase(tbv.begin()); // cerr << "visiting " << u << ' ' << P[u].L << ' ' << P[u].R << '\n'; if(!visited[u]) break; query_ans.clear(); U.get(u+1, M-1, P[u].R + P[u].T + 1); D.get(0, u-1, P[u].R - P[u].T + 1); for(int v: query_ans) { // cerr << u << " -> " << v << '\n'; if(P[v].L <= P[u].R + 1 - abs(P[u].T - P[v].T)) { if(dp[v] > dp[u] + P[v].C) { tbv.erase(pos{v}); dp[v] = dp[u] + P[v].C; tbv.insert(pos{v}); } } } } ll final_ans = INF; for(int i = 0; i < M; i++) if(P[i].R == N) final_ans = min(final_ans, dp[i]); if(final_ans >= INF) final_ans = -1; cout << final_ans << '\n'; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...