답안 #990199

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
990199 2024-05-29T21:13:19 Z MilosMilutinovic 특수한 그래프 (IZhO13_specialg) C++14
100 / 100
116 ms 32468 KB
#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<int> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
    --a[i];
    if (a[i] == -1) {
      a[i] = i;
    }
  }
  int q;
  cin >> q;
  vector<int> op(q), x(q), y(q);
  for (int i = 0; i < q; i++) {
    cin >> op[i];
    if (op[i] == 1) {
      cin >> x[i];
      --x[i];
    } else {
      cin >> x[i] >> y[i];
      --x[i]; --y[i];
    }
  }
  vector<int> b(n, q);
  for (int i = 0; i < q; i++) {
    if (op[i] == 1) {
      b[x[i]] = i;
    }
  }
  vector<int> deg(n);
  for (int i = 0; i < n; i++) {
    deg[a[i]] += 1;
  }
  vector<int> que;
  for (int i = 0; i < n; i++) {
    if (deg[i] == 0) {
      que.push_back(i);
    }
  }
  for (int b = 0; b < (int) que.size(); b++) {
    int i = que[b];
    deg[a[i]] -= 1;
    if (deg[a[i]] == 0) {
      que.push_back(a[i]);
    }
  }
  vector<bool> on_cyc(n, true);
  for (int i : que) {
    on_cyc[i] = false;
  }
  vector<int> dep(n);
  for (int b = (int) que.size() - 1; b >= 0; b--) {
    int i = que[b];
    dep[i] = dep[a[i]] + 1;
  }
  vector<int> pos(n);
  vector<int> idx(n, -1);
  vector<int> sz(n);
  int T = 0;
  for (int i = 0; i < n; i++) {
    if (!on_cyc[i] || idx[i] != -1) {
      continue;
    }
    int x = i;
    int ptr = 0;
    while (idx[x] == -1) {
      pos[x] = ptr;
      idx[x] = T;
      sz[T] += 1;
      ptr += 1;
      x = a[x];
    }
    T += 1;
  }
  const int L = 20;
  vector<vector<int>> jump(n, vector<int>(L));
  for (int i = 0; i < n; i++) {
    jump[i][0] = a[i];
  }
  for (int j = 1; j < L; j++) {
    for (int i = 0; i < n; i++) {
      jump[i][j] = jump[jump[i][j - 1]][j - 1];
    }
  }
  vector<vector<int>> mn(n, vector<int>(L));
  for (int i = 0; i < n; i++) {
    mn[i][0] = b[i];
  }
  for (int j = 1; j < L; j++) {
    for (int i = 0; i < n; i++) {
      mn[i][j] = min(mn[i][j - 1], mn[jump[i][j - 1]][j - 1]);
    }
  }
  vector<int> p(n);
  iota(p.begin(), p.end(), 0);
  function<int(int)> root = [&](int x) {
    return p[x] == x ? x : p[x] = root(p[x]);
  };
  for (int i = 0; i < n; i++) {
    p[root(a[i])] = root(i);
  }
  for (int i = 0; i < q; i++) {
    if (op[i] == 1) {
      continue;
    }
    if (root(x[i]) != root(y[i]) || dep[x[i]] < dep[y[i]]) {
      cout << -1 << '\n';
      continue;
    }
    if (dep[y[i]] > 0) {
      int v = x[i];
      int d = dep[x[i]] - dep[y[i]];
      for (int i = L - 1; i >= 0; i--) {
        if (d >> i & 1) {
          v = jump[v][i];
        }
      }
      if (v != y[i]) {
        cout << -1 << '\n';
        continue;
      }
      v = x[i];
      int res = (int) 1e9;
      for (int i = L - 1; i >= 0; i--) {
        if (d >> i & 1) {
          res = min(res, mn[v][i]);
          v = jump[v][i];
        }
      }
      if (res >= i) {
        cout << d << '\n';
      } else {
        cout << -1 << '\n';
      }
      continue;
    }
    if (dep[x[i]] == 0) {
      int d = (pos[y[i]] - pos[x[i]] + sz[idx[x[i]]]) % sz[idx[x[i]]];
      int v = x[i];
      int res = (int) 1e9;
      for (int i = L - 1; i >= 0; i--) {
        if (d >> i & 1) {
          res = min(res, mn[v][i]);
          v = jump[v][i];
        }
      }
      if (res >= i) {
        cout << d << '\n';
      } else {
        cout << -1 << '\n';
      }
      continue;
    }
    int v = x[i];
    int d = 0;
    int res = (int) 1e9;
    {
      for (int i = L - 1; i >= 0; i--) {
        if (!on_cyc[jump[v][i]]) {
          res = min(res, mn[v][i]);
          d += (1 << i);
          v = jump[v][i];
        }
      }
      res = min(res, mn[v][0]);
      v = a[v];
      d += 1;
    }
    {
      int w = (pos[y[i]] - pos[v] + sz[idx[v]]) % sz[idx[v]];
      for (int i = L - 1; i >= 0; i--) {
        if (w >> i & 1) {
          res = min(res, mn[v][i]);
          d += (1 << i);
          v = jump[v][i];
        }
      }
    }
    if (res >= i) {
      cout << d << '\n';
    } else {
      cout << -1 << '\n';
    }
  }
  return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Correct 2 ms 856 KB Output is correct
2 Correct 2 ms 860 KB Output is correct
3 Correct 2 ms 860 KB Output is correct
4 Correct 3 ms 976 KB Output is correct
5 Correct 2 ms 860 KB Output is correct
6 Correct 6 ms 1240 KB Output is correct
7 Correct 6 ms 1324 KB Output is correct
8 Correct 6 ms 1368 KB Output is correct
9 Correct 6 ms 1372 KB Output is correct
10 Correct 7 ms 1372 KB Output is correct
11 Correct 97 ms 30436 KB Output is correct
12 Correct 78 ms 20052 KB Output is correct
13 Correct 93 ms 26072 KB Output is correct
14 Correct 71 ms 17748 KB Output is correct
15 Correct 81 ms 21068 KB Output is correct
16 Correct 78 ms 20392 KB Output is correct
17 Correct 116 ms 32268 KB Output is correct
18 Correct 98 ms 32468 KB Output is correct
19 Correct 108 ms 32276 KB Output is correct
20 Correct 104 ms 30544 KB Output is correct