Submission #881424

#TimeUsernameProblemLanguageResultExecution timeMemory
88142442kangarooOvertaking (IOI23_overtaking)C++17
19 / 100
2 ms856 KiB
// E. Overtaking #include<bits/stdc++.h> #include "overtaking.h" using namespace std; //#pragma GCC optimize("Ofast,unroll-loops") //#pragma GCC target("avx2,bmi,bmi2,popcnt,lzcnt") template<typename T> using vv_t = vector<vector<T>>; vv_t<long long> neArT; vv_t<long long> arT; vector<long long> s; vector<long long> w; vv_t<long long> backT; long long x; struct Val { long long en, s, e; }; bool operator<(const Val& l, const Val& r) { return l.e < r.e; } vector<Val> resV; int wij(int i, int j, int p) { int l = p - 1, r = s.size(); while (l + 1 < r){ int m = (l + r)/2; if (arT[p][i] + w[i]*(s[m] - s[p]) > arT[p][j] + w[j]*(s[m] - s[p])) r = m; else l = m; } return l; } void init(int L, int N, std::vector<long long> T, std::vector<int> W, int X, int M, std::vector<int> S) { // init arT amd neArT vector<bool> val(N, true); int nn = N; for (int i = 0; i < N; ++i) { if (W[i] <= X) { val[i] = false; nn--; } } N = nn; arT = vv_t<long long>(M - 1, vector<long long>(N)); neArT = vv_t<long long>(M - 1, vector<long long>(N)); backT = vv_t<long long>(M, vector<long long>(N)); for (int i = 0; i < M; ++i) { backT[i].reserve(2*N); } x = X; s = vector<long long>(S.begin(), S.end()); w = vector<long long>(N); vector<long long> t(N); int ind = 0; for (int i = 0; i < W.size(); ++i) { if (val[i]) { t[ind] = T[i]; w[ind++] = W[i]; } } vector<int> o(N); std::iota(o.begin(), o.end(), 0); std::sort(o.begin(), o.end(), [&](int l, int r) { return tie(t[l], w[l]) < tie(t[r], w[r]); }); for (int i = 0; i < N; ++i) { arT[0][o[i]] = t[o[i]]; neArT[0][o[i]] = t[o[i]] + w[o[i]] * (s[1] - s[0]); if (i > 0) neArT[0][o[i]] = max(neArT[0][o[i]], neArT[0][o[i - 1]]); } // for each M for (int i = 1; i < M - 1; ++i) { // sort bus according to departure first, speed second std::sort(o.begin(), o.end(), [&](int l, int r) { return tie(neArT[i - 1][l], w[l]) < tie(neArT[i - 1][r], w[r]); }); // go through sorted and compute next arrival time, keep max of others for (int j = 0; j < N; ++j) { arT[i][o[j]] = neArT[i - 1][o[j]]; // make a prefix max array of the next arrival time neArT[i][o[j]] = arT[i][o[j]] + w[o[j]] * (s[i + 1] - s[i]); if (j > 0) neArT[i][o[j]] = max(neArT[i][o[j]], neArT[i][o[j - 1]]); } } for (int i = 0; i < N; ++i) { backT.back()[i] = neArT.back()[i]; } // sort by arT, w, and then do deque / convex hull opt to find the // find cutting point, by binary search on M for (int i = M - 2; i >= 0; --i) { std::sort(o.begin(), o.end(), [&](int l, int r) { return tie(arT[i][l], w[l]) < tie(arT[i][r], w[l]); }); deque<pair<int,int>> st; for (int j = 0; j < N; ++j) { int po = o[j]; if (j > 0 && arT[i][po] == arT[i][o[j - 1]]) { backT[i][po] = backT[i][o[j - 1]]; } else { int l = -1, r = st.size(); while (l + 1 < r) { int m = (l + r)/2; if (arT[i][po] + x*(s[st[m].second] - s[i]) < arT[i][st[m].first]+ w[st[m].first]*(s[st[m].second] - s[i])) r = m; else l = m; } if (r == st.size()) { backT[i][po] = arT[i][po] + x*(s.back() - s[i]); } else { int ll = i, rr = st[r].second; if (r > 0) { ll = st[r - 1].second; } while (ll + 1 < rr) { int mm = (ll + rr)/2; if (arT[i][po] + x*(s[mm] - s[i]) < arT[i][st[r].first]+ w[st[r].first]*(s[mm] - s[i])) rr = mm; else ll = mm; } backT[i][po] = backT[rr][st[r].first]; } } while (!st.empty() && wij(st.back().first, po, i) >= st.back().second) st.pop_back(); if (!st.empty()) st.push_back({po, wij(st.back().first, po, i)}); else st.push_back({po, M - 1}); if (st.back().second <= i) st.pop_back(); } } // fill in last line by looking at each highest point in order. std::sort(o.begin(), o.end(), [&](int l, int r) { return tie(arT[0][l], w[l]) < tie(arT[0][r], w[r]); }); deque<pair<int,int>> st; for (int i = 0; i < N; ++i) { int po = o[i]; int last = 0; while (!st.empty() && wij(st.back().first, po, 0) >= st.back().second) { for (int j = last + 1; j <= st.back().second; ++j) { if (arT[0][st.back().first] + (w[st.back().first] - x)*(s[j - 1] - s[0]) + 1 > arT[0][po]) break; resV.push_back({backT[j][st.back().first], arT[0][st.back().first] + (w[st.back().first] - x)*(s[j - 1] - s[0]) + 1, min(arT[0][st.back().first] + (w[st.back().first] - x)*(s[j] - s[0]), arT[0][po])}); } last = st.back().second; st.pop_back(); } if (!st.empty()) { for (int j = last + 1; j <= wij(st.back().first, po, 0); ++j) { if (arT[0][st.back().first] + (w[st.back().first] - x)*(s[j - 1] - s[0]) + 1 > arT[0][po]) break; resV.push_back({backT[j][st.back().first], arT[0][st.back().first] + (w[st.back().first] - x)*(s[j - 1] - s[0]) + 1, min(arT[0][st.back().first] + (w[st.back().first] - x)*(s[j] - s[0]), arT[0][po])}); } st.push_back({po, wij(st.back().first, po, 0)}); } else st.push_back({po, M - 1}); if (st.back().second <= 0) st.pop_back(); } int last = 0; while (!st.empty()) { for (int j = last + 1; j <= st.back().second; ++j) { resV.push_back({backT[j][st.back().first], arT[0][st.back().first] + (w[st.back().first] - x)*(s[j - 1] - s[0]) + 1, arT[0][st.back().first] + (w[st.back().first] - x)*(s[j] - s[0])}); } last = st.back().second; st.pop_back(); } } long long arrival_time(long long Y) { int neP = std::lower_bound(resV.begin(), resV.end(), Y, [&](Val l, long long r) { return l.e < r;}) - resV.begin(); if (neP < resV.size() && resV[neP].s <= Y) return resV[neP].en; return Y + x*(s.back() - s.front()); } //502032794

Compilation message (stderr)

overtaking.cpp: In function 'void init(int, int, std::vector<long long int>, std::vector<int>, int, int, std::vector<int>)':
overtaking.cpp:64:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   64 |  for (int i = 0; i < W.size(); ++i) {
      |                  ~~^~~~~~~~~~
overtaking.cpp:117:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::deque<std::pair<int, int> >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  117 |     if (r == st.size()) {
      |         ~~^~~~~~~~~~~~
overtaking.cpp: In function 'long long int arrival_time(long long int)':
overtaking.cpp:179:10: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Val>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  179 |  if (neP < resV.size() && resV[neP].s <= Y) return resV[neP].en;
      |      ~~~~^~~~~~~~~~~~~
#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...