Submission #1212716

#TimeUsernameProblemLanguageResultExecution timeMemory
1212716abczzEscape Route (JOI21_escape_route)C++20
0 / 100
707 ms294976 KiB
#include "escape_route.h"
#include <iostream>
#include <vector>
#include <array>
#include <queue>
#include <algorithm>
#define ll long long

using namespace std;

vector <array<ll, 4>> query;
ll adjid[90];
vector <array<ll, 3>> adj[90];
array <ll, 3> par_edge[90];
vector <array<ll, 3>> tree_edge[90][2];
vector <array<ll, 2>> queryb[90][90];
vector <array<ll, 3>> querya[90];
ll dist[90], X[90], fullday[90][90], reachable[90][90];
priority_queue <array<ll, 3>, vector<array<ll, 3>>, greater<array<ll, 3>>> pq;
priority_queue <array<ll, 2>> rpq;
ll n, q, s;
vector <ll> F;

std::vector<long long> calculate_necessary_time(
    int N, int M, long long S, int Q, std::vector<int> A, std::vector<int> B,
    std::vector<long long> L, std::vector<long long> C, std::vector<int> U,
    std::vector<int> V, std::vector<long long> T) {
  n = N, q = Q, s = S;
  F.resize(q);
  for (int i=0; i<M; ++i) {
    adj[A[i]].push_back({B[i], C[i]-L[i], L[i]});
    adj[B[i]].push_back({A[i], C[i]-L[i], L[i]});
  }
  for (int i=0; i<N; ++i) {
    for (int j=0; j<N; ++j) dist[j] = 1e18, X[j] = -1e18;
    pq.push({0, i, 0});
    dist[i] = 0, X[i] = s-1;
    while (!pq.empty()) {
      auto [w, u, t] = pq.top();
      pq.pop();
      if (dist[u] != w) continue;
      for (auto [v, lim, len] : adj[u]) {
        if (t <= lim && dist[v] > w+len) { 
          dist[v] = w+len;
          pq.push({dist[v], v, t+len});
        }
        else if (t > lim && dist[v] > w+s-t+len) {
          dist[v] = w+s-t+len;
          pq.push({dist[v], v, len});
        }
      }
    }
    for (int j=0; j<N; ++j) fullday[i][j] = dist[j];
    rpq.push({s-1, i});
    while (!rpq.empty()) {
      auto [w, u] = rpq.top();
      rpq.pop();
      if (X[u] != w) continue;
      reachable[u][i] = X[u];
      for (auto [v, lim, len] : adj[u]) {
        if (X[v] < min(lim, X[u]-len)) {
          X[v] = min(lim, X[u]-len);
          rpq.push({X[v], v});
        }
      }
    }
    sort(adj[i].begin(), adj[i].end(), [](auto a, auto b) {
      return a[1] < b[1];
    });
  }
  for (int i=0; i<q; ++i) query.push_back({U[i], V[i], T[i], i});
  sort(query.begin(), query.end(), [](auto a, auto b) {
    return a[2] > b[2];
  });
  for (int i=0; i<q; ++i) {
    if (reachable[query[i][0]][query[i][1]] >= query[i][2]) querya[query[i][0]].push_back({query[i][1], query[i][2], query[i][3]});
    else queryb[query[i][0]][query[i][1]].push_back({query[i][2], query[i][3]});
  }
  for (int i=0; i<n; ++i) {
    for (int j=0; j<n; ++j) {
      vector <array<ll, 2>> cur;
      for (int k=0; k<n; ++k) {
        if (reachable[i][k] >= 0) cur.push_back({reachable[i][k], fullday[k][j]});
      }
      ll f = 1e18;
      sort(cur.begin(), cur.end());
      for (auto [t, id] : queryb[i][j]) {
        while (!cur.empty() && cur.back()[0] >= t) {
          f = min(f, cur.back()[1]);
          cur.pop_back();
        }
        F[id] = f+S-t;
      }
    }
  }
  for (int i=0; i<n; ++i) {
    ll p = S-1;
    reverse(querya[i].begin(), querya[i].end());
    for (int j=0; j<n; ++j) adjid[j] = adj[j].size()-1;
    while (!querya[i].empty()) {
      ll newp = -1;
      for (int j=0; j<n; ++j) {
        dist[j] = 1e18, par_edge[j] = {-1, -1, -1};
        swap(tree_edge[j][0], tree_edge[j][1]);
        tree_edge[j][1].clear();
      }
      dist[i] = p;
      pq.push({p, i, 0});
      while (!pq.empty()) {
        auto [w, u, t] = pq.top();
        pq.pop();
        if (dist[u] != w) continue;
        if (par_edge[u][0] != -1) tree_edge[par_edge[u][0]][1].push_back({u, par_edge[u][1], par_edge[u][2]});
        while (adjid[u] >= 0 && adj[u][adjid[u]][1] >= dist[u]) {
          tree_edge[u][0].push_back(adj[u][adjid[u]]);
          --adjid[u];
        }
        if (adjid[u] >= 0) newp = max(newp, p-dist[u]+adj[u][adjid[u]][1]);
        for (auto [v, lim, len] : tree_edge[u][0]) {
          if (dist[v] > w+len) {
            dist[v] = w+len;
            par_edge[v] = {u, lim, len};
            pq.push({dist[v], v, 0});
          }
        }
      }
      while (!querya[i].empty() && newp < querya[i].back()[1] && querya[i].back()[1] <= p) {
        F[querya[i].back()[2]] = dist[querya[i].back()[0]]-p;
        querya[i].pop_back();
      }
      if (newp == -1) break;
      p = newp;
    }
  }
  return F;
}
#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...