cheater2k

APIO 2015 - Jakarta Skyscrapers

Nov 17th, 2017
320
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.22 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const int N = 30005;
  5. const int inf = 1e9;
  6.  
  7. int n, m;
  8. int b[N], p[N];
  9. vector<int> G[N], a[N];
  10. vector< pair<int,int> > imp;
  11. int *f[N];
  12. int pt[N], *le[N], *ri[N];
  13.  
  14. int pos(int val, int d) {
  15.     int it = lower_bound(G[d].begin(), G[d].end(), val) - G[d].begin();
  16.     assert(G[d][it] == val);
  17.     return it;
  18. }
  19.  
  20. int bfs() {
  21.     for (int i = 1; i < N; ++i) {
  22.         f[i] = new int[G[i].size()];
  23.         for (int j = 0; j < G[i].size(); ++j) f[i][j] = inf;
  24.     }
  25.  
  26.     deque < pair<int,int> > q;
  27.     f[p[0]][pos(b[0], p[0])] = 0;
  28.     q.push_back(make_pair(p[0], pos(b[0], p[0])));
  29.    
  30.     while(!q.empty()) {
  31.         int d = q.front().first, x = q.front().second; q.pop_front();
  32.         int cur = f[d][x];
  33.         int realX = G[d][x];
  34.         if (realX == b[1]) return cur;
  35.  
  36.         if (le[d][x] > -1) {
  37.             if (f[d][le[d][x]] == inf) f[d][le[d][x]] = cur + 1, q.push_back(make_pair(d, le[d][x]));
  38.         }
  39.         if (ri[d][x] < G[d].size()) {
  40.             if (f[d][ri[d][x]] == inf) f[d][ri[d][x]] = cur + 1, q.push_back(make_pair(d, ri[d][x]));
  41.         }
  42.         while(!a[realX].empty()) {
  43.             int new_d = a[realX].back(); a[realX].pop_back();
  44.             int new_pos = pos(realX, new_d);
  45.             if (f[new_d][new_pos] == inf) {
  46.                 f[new_d][new_pos] = cur;
  47.                 q.push_front(make_pair(new_d, new_pos));
  48.             }
  49.         }
  50.     }
  51.  
  52.     return -1;
  53. }
  54.  
  55. void reset(int d, int val) { for (int u : G[d]) pt[u % d] = val; }
  56.  
  57. int main() {
  58.     ios_base::sync_with_stdio(false); cin.tie(0);
  59.     cin >> n >> m;
  60.     for (int i = 0; i < m; ++i) {
  61.         cin >> b[i] >> p[i];
  62.         imp.push_back(make_pair(p[i], b[i] % p[i]));
  63.         a[b[i]].push_back(p[i]);
  64.     }
  65.     sort(imp.begin(), imp.end());
  66.     imp.resize(distance(imp.begin(), unique(imp.begin(), imp.end())));
  67.  
  68.     for (auto &it : imp) {
  69.         int d = it.first, mod = it.second;
  70.         for (int i = mod; i < n; i += d) {
  71.             G[d].push_back(i);
  72.         }
  73.     }
  74.  
  75.     for (int i = 1; i < N; ++i) {
  76.         sort(G[i].begin(), G[i].end());
  77.         le[i] = new int[G[i].size()];
  78.         ri[i] = new int[G[i].size()];
  79.  
  80.         reset(i, -1);
  81.         for (int j = 0; j < G[i].size(); ++j) {
  82.             int cur = G[i][j]; le[i][j] = pt[cur % i]; pt[cur % i] = j;
  83.         }
  84.  
  85.         reset(i, G[i].size());
  86.         for (int j = G[i].size() - 1; j >= 0; --j) {
  87.             int cur = G[i][j]; ri[i][j] = pt[cur % i]; pt[cur % i] = j;
  88.         }
  89.     }
  90.  
  91.     printf("%d\n", bfs());
  92. }
Advertisement
Add Comment
Please, Sign In to add comment