#include <bits/stdc++.h>
using namespace std;
struct Query {
int t, x, y;
Query (int t, int x, int y) : t(t), x(x), y(y) {}
};
const int N = 100005;
int n, m, cnt;
int h[N], p[20][N], nxt[N];
int par[N], deg[N], res[N];
int pos[N], cir[N], sz[N];
bool visit[N], iscir[N];
vector<int> G[N];
vector<Query> query;
void dfs(int u) {
for (auto v : G[u]) {
if (v == p[0][u]) continue;
h[v] = h[u] + 1, dfs(v);
}
}
void find_cir(int u) {
pos[u] = ++sz[cnt], cir[u] = cnt;
if (cir[nxt[u]]) return;
find_cir(nxt[u]);
}
void pre() {
for (int i = 1; i <= n; ++i) {
if (nxt[i]) deg[nxt[i]]++;
}
queue<int> qu;
for (int i = 1; i <= n; ++i) {
if (!deg[i]) qu.push(i);
}
while (qu.size()) {
int u = qu.front(); qu.pop();
if (nxt[u]) {
deg[nxt[u]]--;
if (!deg[nxt[u]]) {
qu.push(nxt[u]);
}
}
}
for (int i = 1; i <= n; ++i) {
if (nxt[i] && !deg[i]) {
p[0][i] = nxt[i], G[nxt[i]].push_back(i);
}
}
for (int i = 1; i <= n; ++i) {
if (!p[0][i]) p[0][i] = i, dfs(i);
}
for (int i = 1; i <= 17; ++i) {
for (int j = 1; j <= n; ++j) {
p[i][j] = p[i - 1][p[i - 1][j]];
}
}
for (int i = 1; i <= n; ++i) {
if (deg[i] && !cir[i]) ++cnt, find_cir(i);
}
}
bool check(int u, int v) {
for (int i = 17; i >= 0; --i) {
if (h[p[i][u]] >= h[v]) u = p[i][u];
}
return u == v;
}
int find(int u) {
return u == par[u] ? u : par[u] = find(par[u]);
}
void join(int u, int v) {
u = find(u), v = find(v);
if (u == v) { iscir[u] = 1; return; }
par[u] = v;
}
int main() {
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; ++i) cin >> nxt[i];
for (int i = 1; i <= n; ++i) par[i] = i;
pre();
cin >> m;
for (int i = 1; i <= m; ++i) {
int t, x, y;
cin >> t; x = y = 0;
if (t == 1) cin >> x, visit[x] = 1;
else cin >> x >> y;
query.push_back(Query(t, x, y));
}
for (int i = 1; i <= n; ++i) {
if (!visit[i] && nxt[i]) join(i, nxt[i]);
}
for (int i = m - 1; i >= 0; --i) {
int t = query[i].t, x = query[i].x, y = query[i].y;
if (t == 1) join(x, nxt[x]);
else {
int px = find(x), py = find(y);
if (px == py) {
if (check(x, y)) res[i] = h[x] - h[y];
else {
int tmp = p[17][x];
if (!cir[tmp] || !cir[px] || cir[tmp] != cir[y]) res[i] = -1;
else {
res[i] = h[x] + pos[y] - pos[tmp];
if (iscir[px]) {
if (pos[tmp] > pos[y]) res[i] += sz[cir[y]];
}
else {
if (pos[tmp] < pos[y]) {
if (pos[tmp] <= pos[px] && pos[px] < pos[y]) res[i] = -1;
}
else {
if (pos[tmp] <= pos[px] || pos[px] < pos[y]) res[i] = -1;
else res[i] += sz[cir[y]];
}
}
}
}
}
else res[i] = -1;
}
}
for (int i = 0; i < m; ++i) {
if (query[i].t == 2) cout << res[i] << '\n';
}
}
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
5 ms |
3196 KB |
Output is correct |
2 |
Correct |
6 ms |
3360 KB |
Output is correct |
3 |
Correct |
6 ms |
3440 KB |
Output is correct |
4 |
Correct |
8 ms |
3760 KB |
Output is correct |
5 |
Correct |
6 ms |
3760 KB |
Output is correct |
6 |
Correct |
15 ms |
4276 KB |
Output is correct |
7 |
Correct |
16 ms |
4620 KB |
Output is correct |
8 |
Correct |
16 ms |
4924 KB |
Output is correct |
9 |
Correct |
17 ms |
5140 KB |
Output is correct |
10 |
Correct |
13 ms |
5432 KB |
Output is correct |
11 |
Correct |
116 ms |
17996 KB |
Output is correct |
12 |
Correct |
103 ms |
17996 KB |
Output is correct |
13 |
Correct |
133 ms |
21168 KB |
Output is correct |
14 |
Correct |
88 ms |
21168 KB |
Output is correct |
15 |
Correct |
92 ms |
22676 KB |
Output is correct |
16 |
Correct |
98 ms |
24180 KB |
Output is correct |
17 |
Correct |
119 ms |
30528 KB |
Output is correct |
18 |
Correct |
120 ms |
32684 KB |
Output is correct |
19 |
Correct |
112 ms |
34720 KB |
Output is correct |
20 |
Correct |
107 ms |
34904 KB |
Output is correct |