比赛 |
EYOI与SBOI开学欢乐赛13th |
评测结果 |
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA |
题目名称 |
会合(Rendezvous) |
最终得分 |
100 |
用户昵称 |
ZRQ |
运行时间 |
8.031 s |
代码语言 |
C++ |
内存使用 |
88.23 MiB |
提交时间 |
2022-10-21 21:02:36 |
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N=500005;
int n,q,to[N],a,b,lw[N],df[N],clk,ring[N],r,s[N],top,fa[N][22],bs[N],dep[N],pos[N],cnt[N];
bool vis[N];
vector<int> ns[N],fr[N];
char ch;
inline void read(int &x){x=0;ch=getchar();while(ch<48||ch>57)ch=getchar();while(ch>47&&ch<58)x=(x<<3)+(x<<1)+(ch^48),ch=getchar();}
void tarjan(int cur)
{
df[cur]=lw[cur]=++clk;
s[++top]=cur;
vis[cur]=1;
if(!df[to[cur]]) tarjan(to[cur]),lw[cur]=min(lw[cur],lw[to[cur]]);
else if(vis[cur]) lw[cur]=min(lw[cur],df[to[cur]]);
if(df[cur]==lw[cur])
{
int x;
++r;
int k=0;
do
{
x=s[top--];
pos[x]=++k;
vis[x]=0;
ring[x]=r;
ns[r].push_back(x);
}while(x!=cur);
cnt[r]=k;
}
return ;
}
void DFS(int cur,int lst,int rg)
{
fa[cur][0]=lst;
bs[cur]=rg;
for(int i=1;i<=20;++i)
fa[cur][i]=fa[fa[cur][i-1]][i-1];
for(int i=0;i<fr[cur].size();++i)
if(cnt[ring[fr[cur][i]]]<=1)
dep[fr[cur][i]]=dep[cur]+1,DFS(fr[cur][i],cur,rg);
return ;
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=20;i>=0;--i)
if((1<<i)<=dep[x]-dep[y])
x=fa[x][i];
if(x==y) return x;
for(int i=20;i>=0;--i)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int main()
{
freopen("rdz.in","r",stdin);
freopen("rdz.out","w",stdout);
read(n),read(q);
for(int i=1;i<=n;++i)
{
read(to[i]);
if(i!=to[i]) fr[to[i]].push_back(i);
}
for(int i=1;i<=n;++i)
if(!df[i])
tarjan(i);
for(int i=1;i<=n;++i)
if(i==to[i]||cnt[ring[i]]>1)
DFS(i,0,i);
for(int i=1;i<=q;++i)
{
read(a),read(b);
if(ring[bs[a]]!=ring[bs[b]])
{
printf("-1 -1\n");
continue;
}
if(bs[a]==bs[b])
{
int lca=LCA(a,b);
printf("%d %d\n",dep[a]-dep[lca],dep[b]-dep[lca]);
}
else//ring
{
int disa,disb,da,db;
if(pos[bs[a]]>pos[bs[b]]) disa=pos[bs[a]]-pos[bs[b]];
else disa=pos[bs[a]]+cnt[ring[bs[a]]]-pos[bs[b]];
disb=cnt[ring[bs[a]]]-disa;
da=dep[a]-dep[bs[a]];
db=dep[b]-dep[bs[b]];
if(max(da+disa,db)!=max(db+disb,da))
{
if(max(da+disa,db)<=max(db+disb,da)) printf("%d %d\n",da+disa,db);
else printf("%d %d\n",da,db+disb);
}
else if(min(da+disa,db)!=min(db+disb,da))
{
if(min(da+disa,db)<=min(db+disb,da)) printf("%d %d\n",da+disa,db);
else printf("%d %d\n",da,db+disb);
}
else
{
if(da>=disb+db) printf("%d %d\n",da,disb+db);
else printf("%d %d\n",da+disa,db);
}
}
}
return 0;
}