danielvitor23

Untitled

Apr 13th, 2021
1,095
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.70 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAX = 2e5+5;
  4.  
  5. int is_cycle[MAX], cycle[MAX], line[MAX];
  6. int count_cycle, count_line, pos_cycle[MAX], sz_cycle[MAX];
  7. int color[MAX], up[MAX][32];
  8. vector<int> order;
  9. int n, q;
  10.  
  11. void dfs(int u) {
  12.     order.push_back(u);
  13.     color[u] = 1;
  14.     if (color[up[u][0]] == 1) {
  15.         int to = order.size();
  16.         int cnt = 0;
  17.         do {
  18.             ++cnt;
  19.             --to;
  20.             is_cycle[order[to]] = true;
  21.             cycle[order[to]] = count_cycle;
  22.         } while (to >= 0 and order[to] != up[u][0]);
  23.         to = order.size()-cnt;
  24.         for (int i = to; i < (int)order.size(); ++i) {
  25.             pos_cycle[order[i]] = i-to;
  26.         }
  27.         sz_cycle[count_cycle] = cnt;
  28.         ++count_cycle;
  29.     } else if (color[up[u][0]] == 0) {
  30.         dfs(up[u][0]);
  31.     }
  32.     if (!is_cycle[u]) {
  33.         if (is_cycle[up[u][0]] == 1) {
  34.             line[u] = count_line++;
  35.         } else {
  36.             line[u] = line[up[u][0]];
  37.         }
  38.     }
  39.     color[u] = 2;
  40.     order.pop_back();
  41. }
  42.  
  43. void same_cycle(int a, int b, int dd=0) {
  44.     if (cycle[a] != cycle[b]) {
  45.         cout << "-1\n";
  46.     } else {
  47.         cout << dd+(pos_cycle[b] - pos_cycle[a] + sz_cycle[cycle[a]]) % sz_cycle[cycle[a]] << '\n';
  48.     }
  49. }
  50.  
  51. int dist(int node) {
  52.     int dd = 0;
  53.     for (int k = 30; k >= 0; --k) {
  54.         if (!is_cycle[up[node][k]]) {
  55.             node = up[node][k];
  56.             dd += (1 << k);
  57.         }
  58.     }
  59.     node = up[node][0];
  60.     return dd + 1;
  61. }
  62.  
  63. int main() {
  64.     ios_base::sync_with_stdio(0), cin.tie(0);
  65.     cin >> n >> q;
  66.     memset(up, -1, sizeof up);
  67.     memset(line, -1, sizeof line);
  68.     memset(cycle, -1, sizeof cycle);
  69.     memset(pos_cycle, -1, sizeof pos_cycle);
  70.     for (int i = 0, a; i < n; ++i) {
  71.         cin >> a, --a;
  72.         up[i][0] = a;
  73.     }
  74.     for (int k = 1; k < 31; ++k) {
  75.         for (int i = 0; i < n; ++i) {
  76.             if (~up[i][k-1]) up[i][k] = up[up[i][k-1]][k-1];
  77.         }
  78.     }
  79.     for (int i = 0; i < n; ++i) {
  80.         if (color[i] == 0) {
  81.             dfs(i);
  82.         }
  83.     }
  84.     int a, b;
  85.     while (q--) {
  86.         cin >> a >> b, --a, --b;
  87.         if (is_cycle[a] and is_cycle[b]) {
  88.             same_cycle(a, b);
  89.         } else if (is_cycle[a]) {
  90.             cout << "-1\n";
  91.         } else if (is_cycle[b]) {
  92.             int ans = 0;
  93.             for (int k = 30; k >= 0; --k) {
  94.                 if (!is_cycle[up[a][k]]) {
  95.                     a = up[a][k];
  96.                     ans += (1 << k);
  97.                 }
  98.             }
  99.             a = up[a][0];
  100.             same_cycle(a, b, ans+1);
  101.         } else {
  102.             if (line[a] != line[b]) {
  103.                 cout << "-1\n";
  104.             } else {
  105.                 int da = dist(a);
  106.                 int db = dist(b);
  107.                 if (db >= da) {
  108.                     if (a != b) {
  109.                         cout << "-1\n";
  110.                     } else {
  111.                         cout << "0\n";
  112.                     }
  113.                 } else {
  114.                     int diff = da-db;
  115.                     int ans = 0;
  116.                     for (int k = 30; k >= 0; --k) {
  117.                         if (diff >= (1 << k)) {
  118.                             a = up[a][k];
  119.                             diff -= (1 << k);
  120.                             ans += (1 << k);
  121.                         }
  122.                     }
  123.                     if (a != b) {
  124.                         cout << "-1\n";
  125.                     } else {
  126.                         cout << ans << '\n';
  127.                     }
  128.                 }
  129.             }
  130.         }
  131.     }
  132. }
Advertisement
Add Comment
Please, Sign In to add comment