比赛 |
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;
}