比赛 EYOI与SBOI开学欢乐赛13th 评测结果 AAATAATAAAAAAAWAAAAAAAAWAAWAAAAA
题目名称 会合(Rendezvous) 最终得分 84
用户昵称 op_组撒头屯 运行时间 9.710 s
代码语言 C++ 内存使用 115.41 MiB
提交时间 2022-10-21 20:37:25
显示代码纯文本
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=500000+5;
  4. struct wer{
  5. int to,next;
  6. }eg[2*N];
  7. int head[N],ne=1,t[N];
  8. void add(int x,int y){
  9. eg[++ne]={y,head[x]};
  10. head[x]=ne;return ;
  11. }
  12. int n,q,lgn;
  13. int vis[N]={0};
  14. bool in[N],huan[N];
  15. int st[N],tp=0,cnt=0,tot=0;
  16. vector<int>v[N],fr[N];
  17. int d[N],c[N],anc[N][30];
  18. int rt[N],hid[N],hpos[N],dir[N];
  19. void dfs(int pt,int lst){
  20. st[++tp]=pt;vis[pt]=1;
  21. for (int i=head[pt];i!=0;i=eg[i].next){
  22. int x=eg[i].to;
  23. if (i==(lst^1)||vis[x]==2)continue;
  24. if (vis[x]==1){
  25. cnt++;
  26. while(st[tp]!=x){
  27. v[cnt].push_back(st[tp]);
  28. vis[st[tp]]=2;huan[st[tp]]=1;tp--;
  29. }
  30. v[cnt].push_back(x);huan[x]=1;vis[x]=2;tp--;
  31. return ;
  32. }
  33. if (vis[x]==0) dfs(x,i);
  34. }
  35. vis[pt]=2;tp--;
  36. return ;
  37. }
  38. int dep[N];
  39. void dfs2(int pt,int id,int id2){
  40. c[pt]=id;d[pt]=id2;
  41. for (int i=0;i<fr[pt].size();i++){
  42. int x=fr[pt][i];
  43. if (huan[x])continue;
  44. dep[x]=dep[pt]+1;anc[x][0]=pt;
  45. dfs2(x,id,id2);
  46. }
  47. return ;
  48. }
  49. int lca(int a,int b){
  50. if (dep[a]<dep[b])swap(a,b);
  51. for (int i=lgn;i>=0;i--){
  52. if (anc[a][i]!=0&&dep[anc[a][i]]>=dep[b])a=anc[a][i];
  53. if (a==b)return a;
  54. }
  55. for (int i=lgn;i>=0;i--){
  56. if (anc[a][i]!=anc[b][i]){
  57. a=anc[a][i];b=anc[b][i];
  58. }
  59. }
  60. return anc[a][0];
  61. }
  62. struct sdf{
  63. int x,y;
  64. }ans[4];
  65. bool cmp(sdf a,sdf b){
  66. if (max(a.x,a.y)!=max(b.x,b.y))return max(a.x,a.y)<max(b.x,b.y);
  67. if (min(a.x,a.y)!=min(b.x,b.y))return min(a.x,a.y)<min(b.x,b.y);
  68. return a.x>=a.y;
  69. }
  70. int main(){
  71. freopen ("rdz.in","r",stdin);
  72. freopen ("rdz.out","w",stdout);
  73. scanf("%d%d",&n,&q);
  74. lgn=1.0*log(n)/log(2);
  75. for (int i=1;i<=n;i++){
  76. int x;scanf("%d",&x);
  77. in[x]=1;fr[x].push_back(i);
  78. add(i,x);add(x,i);t[i]=x;
  79. }
  80. for (int i=1;i<=n;i++){
  81. if (!vis[i])dfs(i,0);
  82. }
  83. for (int i=1;i<=cnt;i++){
  84. for (int j=0;j<v[i].size();j++){
  85. int x=v[i][j];
  86. dep[x]=0;dfs2(x,++tot,i);
  87. hpos[x]=j+1;hid[x]=i;rt[tot]=x;
  88. }
  89. if (v[i].size()==1)continue;
  90. if (t[v[i][1]]==v[i][2])dir[i]=1;
  91. else dir[i]=2;
  92. }
  93. for (int i=1;i<=lgn;i++){
  94. for (int j=1;j<=n;j++)anc[j][i]=anc[anc[j][i-1]][i-1];
  95. }
  96. while(q--){
  97. int a,b;scanf("%d%d",&a,&b);
  98. if (d[a]!=d[b]){
  99. printf("-1 -1\n");continue;
  100. }
  101. if (c[a]==c[b]){
  102. int l=lca(a,b);
  103. printf("%d %d\n",dep[a]-dep[l],dep[b]-dep[l]);
  104. }
  105. else{
  106. int x=hpos[rt[c[a]]],y=hpos[rt[c[b]]];
  107. int sz=v[hid[rt[c[a]]]].size();
  108. int lena=(y-x+sz)%sz,lenb=(x-y+sz)%sz;
  109. if (dir[hid[rt[c[a]]]]==2)swap(lena,lenb);
  110. ans[1]={lena+dep[a],dep[b]},ans[2]={dep[a],lenb+dep[b]};
  111. sort(ans+1,ans+3,cmp);
  112. printf("%d %d\n",ans[1].x,ans[1].y);
  113. }
  114. }
  115. return 0;
  116. }
  117.