比赛 EYOI与SBOI开学欢乐赛13th 评测结果 TWWTWWTAAWAWWWTWTWAWWWWTAATWWATW
题目名称 会合(Rendezvous) 最终得分 21
用户昵称 HeSn 运行时间 13.149 s
代码语言 C++ 内存使用 120.18 MiB
提交时间 2022-10-21 21:42:25
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int MAXN = 500010;
int n, m, inc[MAXN], fa[MAXN], stp[MAXN], num[MAXN], len[MAXN], dep[MAXN], f[20][MAXN], bel[MAXN], cnt;
vector<int> cd[MAXN];
int find(int x) {
	if(x == fa[x]) {
		return x;
	}
	return fa[x] = find(fa[x]);
}
void dfs(int x, int fath, int rt) {
	bel[x] = rt;
	for(int i = 0; i < cd[x].size(); i ++) {
		int u = cd[x][i];
		if(inc[u] || u == fath) {
			continue;
		}
		dep[u] = dep[x] + 1;
		int a = find(u), b = find(x);
		fa[a] = b;
		dfs(u, x, rt);
	}
}
int lca(int x, int y) {
	if(dep[x] < dep[y]) {
		swap(x, y);
	}
	for(int i = 20; i >= 0; i --) {
		int u = f[i][x];
		if(dep[u] >= dep[y]) {
			x = u;
		}
	}
	if(x == y) {
		return x;
	}
	for(int i = 20; i >= 0; i --) {
		int u = f[i][x], v = f[i][y];
		if(u != v) {
			x = u;
			y = v;
		}
	}
	return f[0][x];
}
void find_circle(int x, int id, int s) {
    if(stp[x]) {
    	return ;
	}
    num[x] = id;
	len[id] ++;
	stp[x] = s;
    find_circle(f[0][x], id, s + 1);
}
int check(int a, int b, int c, int d) {
	
}
signed main() {
    freopen("rdz.in", "r", stdin);
    freopen("rdz.out", "w", stdout);
	cin >> n >> m;
	for(int i = 1; i <= n; i ++) {
		fa[i] = i;
		int x;
		cin >> x;
		f[0][i] = x;
		cd[x].push_back(i);
		inc[x] ++;
	}
	queue<int> q;
	for(int i = 1; i <= n; i ++) {
		if(!inc[i]) {
			q.push(i);
		}
	}
	while(!q.empty()) {
		int x = q.front();
		q.pop();
		int u = f[0][x];
		inc[u] --;
		if(!inc[u]) {
			q.push(u);
		}
	}
	for(int i = 1; i <= n; i ++) {
		if(inc[i]) {
			dfs(i, 0, i);
			if(!stp[i]) {
				find_circle(i, ++ cnt, 1);
			}
		}
	}
	for(int i = 1; i <= 20; i ++) {
		for(int j = 1; j <= n; j ++) {
			f[i][j] = f[i - 1][f[i - 1][j]];
		}
	}
	for(int i = 1; i <= m; i ++) {
		int x, y;
		cin >> x >> y;
		if(find(x) != find(y)) {
			cout << -1 << ' ' << -1 << endl;
			continue;
		}
		if(bel[x] == bel[y]) {
			int w = lca(x, y);
			cout << dep[x] - dep[w] << ' ' << dep[y] - dep[w] << endl;
		}
		else {
			int u = bel[x], v = bel[y];
            int ans1 = dep[x] + (stp[v] - stp[u] + len[num[u]]) % len[num[u]];
			int ans2 = dep[v] + (stp[u] - stp[v] + len[num[u]]) % len[num[u]];
			if(check(dep[x], ans2, ans1, dep[y])) {
				cout << dep[x] << ' ' << ans2 << endl;
			}
            else {
            	cout << ans1 << ' ' << dep[y] << endl;
			}
		}
	}
	return 0;
}