Submission #651705

#TimeUsernameProblemLanguageResultExecution timeMemory
651705pauloamedJakarta Skyscrapers (APIO15_skyscraper)C++17
57 / 100
1094 ms157384 KiB
#include<bits/stdc++.h>
using namespace std;

#define int long long

const int MAXN = 30010;

vector<int> p2bs[MAXN];
unordered_map<int,int> p2d[MAXN];
vector<int> col2p[MAXN];

unordered_map<int,int> ans[MAXN];

void print(){
  for(int i = 0; i < MAXN; ++i){
    if(ans[i].empty()) continue;
    cout << i << ":\n";
    for(auto [x, val] : ans[i]){
      cout << "\t" << x << ": " << val << "\n";
    }
  }
  cout << "================\n";
}

int32_t main(){
  cin.tie(NULL)->sync_with_stdio(false);

  int n, m; cin >> n >> m;

  int B[2], P[2];
  cin >> B[0] >> P[0];
  cin >> B[1] >> P[1];

  for(int i = 2; i < m; ++i){
    int b, p; cin >> b >> p;
    p2bs[p].push_back(b);
  }

  for(int p = 1; p < MAXN; ++p){
    auto &D = p2d[p];

    sort(p2bs[p].begin(), p2bs[p].end());
    p2bs[p].erase(unique(p2bs[p].begin(), p2bs[p].end()), p2bs[p].end());

    queue<int> q;
    for(auto b : p2bs[p]){
      col2p[b].push_back(p);
      q.push(b);
      D[b] = 0;
    }
    while(q.size()){
      auto x = q.front(); q.pop();

      if(x - p >= 0 && D.count(x - p) == 0){
        D[x - p] = D[x] + 1;
        q.push(x - p);
      }
      if(x + p < n && D.count(x + p) == 0){
        D[x + p] = D[x] + 1;
        q.push(x + p);
      }
    }
  }

  // cout << "P2D\n";
  // for(int p = 1; p < MAXN; ++p){
  //   if(p2d[p].empty()) continue;
  //   cout << p << ": \n";
  //   for(auto [x, val] : p2d[p]){
  //     cout << "\t" << x << " " << val << endl;
  //   }
  // }
  // cout << "================\n";

  struct Node{
    int i, x;
    // se i == -1, eh col
    int cost;
    bool operator<(const Node &n) const{
      return cost > n.cost;
    }
  };

  priority_queue<Node> pq;
  for(int i = (B[0] % P[0]); i < n; i += P[0]){
    int dist = abs(i - B[0]) / P[0];
    pq.push({-1, i, ans[0][i] = dist});
  }

  // print();

  while(pq.size()){
    auto maybe_update = [&](int p, int x, int val){
      if(ans[p + 1].count(x) == 0 || ans[p + 1][x] > val){
        pq.push({p, x, ans[p + 1][x] = val});
      }
    };

    auto [i, x, cost] = pq.top(); pq.pop();
    if(cost > ans[i + 1][x]) continue;

    // cout << i << " " << x << " " << cost << "\n";

    if(i == -1){
      for(auto p : col2p[x]){
        maybe_update(p, x, cost + p2d[p][x]);
      }
    }else{
      // sou power i na coluna x
      maybe_update(-1, x, cost);

      if(x + i < n){
        maybe_update(i, x + i, cost + 1);
      }

      if(x - i >= 0){
        maybe_update(i, x - i, cost + 1);
      }
    }

    // print();
  }

  // print();

  if(ans[0].count(B[1]) == 0) cout << -1 << "\n";
  else cout << ans[0][B[1]] << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...