提交时间:2024-11-28 16:19:24
运行 ID: 35192
#include <bits/stdc++.h> using namespace std; #define endl "\n" #define int long long int n,l,r; int p[200300]; int p_2[200030][21],pl[200300],pr[200300]; int d[510][510]; int q; int f[200030]; inline int ff(int x){return f[x]==x?x:f[x]==ff(f[x]);} inline void merge(int x,int y){f[ff(x)]=ff(y);} bool rng[200300]; bool vis[200300]; int ic[200300]; int dep[200300],bel[200300],siz[200300],rt[200300],id; vector<int>g[200300]; inline void dfs(int u){ for(int v:g[u])if(!rng[v]){ bel[v]=bel[u]; dep[v]=dep[u]+1; rt[v]=rt[u]; dfs(v); } } inline int dis(int x,int y){ if(bel[x]!=bel[y])return -1; if(rng[x]&&!rng[y])return -1; if(!rng[x]&&!rng[y]&&rt[x]!=rt[y])return -1; if(rng[x]&&rng[y])return (dep[y]+siz[bel[y]]-dep[x])%siz[bel[y]]; if(!rng[x]&&rng[y])return dep[x]-dep[rt[x]]+dis(rt[x],y); if(dep[x]<dep[y])return -1; int w=dep[x]-dep[y]; for(int i=20;i>=0;i--) if((w>>i)&1)x=p_2[x][i]; if(x!=y)return -1; return w; } inline bool chk(int x,int y,int len,int z){ if(!rng[x]&&!rng[y]){ if(rng[z])return 0; return dep[x]>=dep[z]&&dep[z]>=dep[y]; } else if(!rng[x]){ int p=rt[x]; return chk(x,p,dep[p]-dep[x],z)|chk(p,y,len-(dep[p]-dep[x]),z); } else{ if(!rng[z])return 0; return (dep[z]+siz[bel[z]]-dep[x])%siz[bel[z]]<=len; } } inline int force(int x,int y){ if(x==y)return 0; if(dis(x,y)==-1)return -1; if(!rng[x]&&!rng[y]){ int d=dep[x]-dep[y]; if(d/l*r>=d)return (d+r-1)/r; else return -1; } int t=0; int L=x,R=x; int len=0; while(1){ t++; L=pl[L],R=pr[R]; // cout<<L<<" "<<R<<endl; len+=r-l; if(chk(L,R,len,y))break; if(t>n)return -1; } return t; } signed main(){ ios::sync_with_stdio(0); cin.tie(0),cout.tie(0); // freopen("oneness.in","r",stdin); // freopen("oneness.out","w",stdout); cin>>n>>l>>r; for(int i=1;i<=n;i++) cin>>p[i],p_2[i][0]=p[i],merge(i,p[i]),ic[p[i]]++,rng[i]=1,g[p[i]].push_back(i); for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) p_2[i][j]=p_2[p_2[i][j-1]][j-1]; for(int i=1;i<=n;i++){ pl[i]=pr[i]=i; for(int j=20;j>=0;j--) if((l>>j)&1)pl[i]=p_2[pl[i]][j]; for(int j=20;j>=0;j--) if((r>>j)&1)pr[i]=p_2[pr[i]][j]; } queue<int>Q; for(int i=1;i<=n;i++) if(!ic[i])Q.push(i); int ps=0; while(!Q.empty()){ int u=Q.front(); Q.pop(); ps++; ic[p[u]]--; rng[u]=0; if(ic[p[u]]==0)Q.push(p[u]); } for(int i=1;i<=n;i++)if(rng[i]&&!vis[i]){ int x=i; id++; while(!vis[x]){ siz[id]++; dep[x]=siz[id]; vis[x]=1; rt[x]=x; bel[x]=id; dfs(x); x=p[x]; } } cin>>q; if(n<=500){ memset(d,0x3f,sizeof(d)); for(int i=1;i<=n;i++){ int x=i; for(int j=1;j<=r;j++){ x=p[x]; if(j>=l&&j<=r)d[i][x]=1; } d[i][i]=0; } for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) d[i][j]=min(d[i][j],d[i][k]+d[k][j]); while(q--){ int x,y; cin>>x>>y; if(d[x][y]>=1e18)cout<<-1<<endl; else cout<<d[x][y]<<endl; } } else if(l==1&&r==1){ while(q--){ int x,y; cin>>x>>y; cout<<dis(x,y)<<endl; } } else if(l==1){ while(q--){ int x,y; cin>>x>>y; int d=dis(x,y); if(d==-1)cout<<-1<<endl; else cout<<(d+r-1)/r<<endl; } } else { while(q--){ int x,y; cin>>x>>y; cout<<force(x,y)<<endl; } } cout.flush(); return 0; }