Submission #986493

#TimeUsernameProblemLanguageResultExecution timeMemory
986493boris_mihovEscape Route 2 (JOI24_escape2)C++17
100 / 100
245 ms51024 KiB
#include <algorithm> #include <iostream> #include <numeric> #include <cassert> #include <vector> #include <map> #include <set> typedef long long llong; const int MAXN = 100000 + 10; const int MAXQ = 300000 + 10; const int BUCKET_SIZE = 317; const llong INF = 1e18; int n, q, t; struct Flight { int from; int to; int idx; }; int cntFlights; int inTime[MAXN]; llong answer[MAXQ]; llong answer2[MAXN]; std::vector <Flight> v[MAXN]; std::vector <int> minimumTo[MAXN]; std::vector <std::pair <int,int>> g[MAXN]; std::vector <std::pair <int,int>> queries[MAXN]; std::vector <std::pair <int,int>> byLevel[MAXN]; llong toRemove[MAXN]; int flightFrom[MAXN]; int flightTo[MAXN]; int parent[MAXN]; int parEdge[MAXN]; int parEdge2[MAXN]; int dep[MAXN]; llong dist[MAXN]; void buildTree(int node) { // std::cout << "build tree: " << node << ' ' << dep[node] << ' ' << dist[node] << '\n'; for (const auto &[u, val] : g[node]) { dep[u] = dep[node] + 1; dist[u] = dist[node] + val; buildTree(u); } } void solveDFS(int node) { // std::cout << "here: " << node << ' ' << dep toRemove[dep[node]] = dist[node] - parEdge2[node]; for (const auto &[level, idx] : byLevel[dep[node]]) { answer[idx] = std::min(answer[idx], dist[node] - toRemove[level]); } for (const auto &[u, val] : g[node]) { solveDFS(u); } } int specialDep; llong solveDFS2(int node) { if (dep[node] == specialDep) { answer2[dep[node]] = std::min(answer2[dep[node]], (llong)parEdge2[node]); return dist[node]; } llong minAdd = INF; for (const auto &[u, val] : g[node]) { minAdd = std::min(minAdd, solveDFS2(u)); } answer2[dep[node]] = std::min(answer2[dep[node]], minAdd - dist[node] + parEdge2[node]); return minAdd; } void solve() { for (int i = 1 ; i < n ; ++i) { std::sort(v[i].begin(), v[i].end(), [&](auto x, auto y) { return x.from < y.from || (x.from == y.from && x.to < y.to); }); for (int j = 0 ; j < v[i].size() ; ++j) { v[i][j].idx = ++cntFlights; flightFrom[v[i][j].idx] = v[i][j].from; flightTo[v[i][j].idx] = v[i][j].to; } } cntFlights++; for (const Flight &f : v[n - 1]) { parent[f.idx] = cntFlights; parEdge2[f.idx] = f.to - f.from; g[cntFlights].push_back({f.idx, f.to - f.from}); } for (int i = n - 2 ; i >= 1 ; --i) { minimumTo[i + 1].resize(v[i + 1].size()); minimumTo[i + 1].back() = v[i + 1][v[i + 1].size() - 1].idx; for (int j = (int)v[i + 1].size() - 2 ; j >= 0 ; --j) { minimumTo[i + 1][j] = minimumTo[i + 1][j + 1]; if (v[i + 1][j].to < flightTo[minimumTo[i + 1][j]]) { minimumTo[i + 1][j] = v[i + 1][j].idx; } } for (int j = 0 ; j < v[i].size() ; ++j) { int l = -1, r = v[i + 1].size(), mid; while (l < r - 1) { mid = (l + r) / 2; if (v[i + 1][mid].from < v[i][j].to) l = mid; else r = mid; } if (r != v[i + 1].size()) { parent[v[i][j].idx] = minimumTo[i + 1][r]; parEdge[v[i][j].idx] = flightFrom[minimumTo[i + 1][r]] - v[i][j].from; parEdge2[v[i][j].idx] = v[i][j].to - v[i][j].from; g[minimumTo[i + 1][r]].push_back({v[i][j].idx, flightFrom[minimumTo[i + 1][r]] - v[i][j].from}); } else { parent[v[i][j].idx] = minimumTo[i + 1][0]; parEdge[v[i][j].idx] = t - v[i][j].from + flightFrom[minimumTo[i + 1][0]]; parEdge2[v[i][j].idx] = v[i][j].to - v[i][j].from; g[minimumTo[i + 1][0]].push_back({v[i][j].idx, t - v[i][j].from + flightFrom[minimumTo[i + 1][0]]}); } } } for (int i = 1 ; i <= q ; ++i) { answer[i] = INF; } buildTree(cntFlights); for (int l = 1 ; l <= n ; ++l) { if (v[l].size() < BUCKET_SIZE) { for (const auto &[r, idx] : queries[l]) { // std::cout << "add query: " << n - l << ' ' << n - (r - 1) << ' ' << idx << '\n'; byLevel[n - l].push_back({n - (r - 1), idx}); /*answer[idx] = INF; for (const Flight &f : v[l]) { llong curr = 0; int flightIdx = f.idx; int times = r - l - 1; for (int i = 0 ; i < times ; ++i) { curr += parEdge[flightIdx]; flightIdx = parent[flightIdx]; } curr += parEdge2[flightIdx]; answer[idx] = std::min(answer[idx], curr); }*/ } } else { std::fill(answer2, answer2 + n, INF); specialDep = n - l; solveDFS2(cntFlights); for (const auto &[r, idx] : queries[l]) { answer[idx] = answer2[n - r + 1]; } } } solveDFS(cntFlights); } void print() { for (int i = 1 ; i <= q ; ++i) { std::cout << answer[i] << '\n'; } } void input() { std::cin >> n >> t; for (int i = 1 ; i < n ; ++i) { int sz; std::cin >> sz; v[i].resize(sz); for (int j = 0 ; j < sz ; ++j) { std::cin >> v[i][j].from >> v[i][j].to; } } std::cin >> q; for (int i = 1 ; i <= q ; ++i) { int l, r; std::cin >> l >> r; queries[l].push_back({r, i}); } } void fastIOI() { std::ios_base :: sync_with_stdio(0); std::cout.tie(nullptr); std::cin.tie(nullptr); } int main() { fastIOI(); input(); solve(); print(); return 0; }

Compilation message (stderr)

Main.cpp: In function 'void solve()':
Main.cpp:95:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Flight>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   95 |         for (int j = 0 ; j < v[i].size() ; ++j)
      |                          ~~^~~~~~~~~~~~~
Main.cpp:124:28: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Flight>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  124 |         for (int j = 0 ; j < v[i].size() ; ++j)
      |                          ~~^~~~~~~~~~~~~
Main.cpp:134:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<Flight>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  134 |             if (r != v[i + 1].size())
      |                 ~~^~~~~~~~~~~~~~~~~~
#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...