Description

In the NN country, there are n cities, numbered from 1 to n, and n−1 roads, connecting them. There is a roads path between any two cities.

There are m bidirectional bus routes between cities. Buses drive between two cities taking the shortest path with stops in every city they drive through. Travelling by bus, you can travel from any stop on the route to any other. You can travel between cities only by bus.

You are interested in q questions: is it possible to get from one city to another and what is the minimum number of buses you need to use for it?

Input

The first line contains a single integer n (2≤n≤2⋅105) — the number of cities.

The second line contains n−1 integers p2,p3,…,pn (1≤pi<i), where pi means that cities pi and i are connected by road.

The third line contains a single integer m (1≤m≤2⋅105) — the number of bus routes.

Each of the next m m lines contains 2 integers a and b (1≤a,b≤n, a≠b), meaning that there is a bus route between cities a and b. It is possible that there is more than one route between two cities.

The next line contains a single integer q (1≤q≤2⋅105) — the number of questions you are interested in.

Output

Print the answer for each question on a separate line. If there is no way to get from one city to another, print −1. Otherwise print the minimum number of buses you have to use.

题意:给定一棵 $n$ 个点的树, $m$ 条链, $q$ 个询问,每次询问 $a$ 到 $b$ 之间的路径最少可用几条给定链完全覆盖,无解输出 $-1$ 。

分析:

对于每一条 $a$ 与$b$ 间的路径,都可拆分为 $a$ 到 $lca$ 的路径和 $b$ 到 $lca$ 的路径

采用贪心策略, $low[x][i]$ 表示从 $x$ 点出发向上选择不超过 $2^i$ 条链可抵达的深度最浅的点。这时对于每一个询问可将询问的两个端点修改为利用贪心策略跳到的深度大于 $lca$ 且深度最小的节点,并记录下答案,这个过程可以用倍增完成。注意特判端点即 $lca$ 的情况。

然后出现两种情况。若修改后的两个端点出现在同一条给定链上,答案为原答案 $+1$ ,否则答案为原答案 $+2$ 。问题模型转换为,每次询问一个点对是否出现在同一条给定链上。记录下 $dfs$ 序,在深搜过程中利用树状数组统计即可。

时间复杂度 $O(nlogn)$ 。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. #include<vector>
  5. #define LL long long
  6. using namespace std;
  7. const int N=2e5+;
  8. const int inf=0x3f3f3f3f;
  9. int n,m,Q,cnt,val,x,y,ind;
  10. int deep[N],in[N],out[N],last[N];
  11. int first[N],ans[N],tr[N];
  12. int fa[N][],low[N][];
  13. bool ok[N];
  14. vector<int> a[N],b[N];
  15. struct edge{int to,next;}e[N];
  16. struct chain{int x,y,t;}c[N],q[N];
  17. int read()
  18. {
  19. int x=,f=;char c=getchar();
  20. while(c<''||c>''){if(c=='-')f=-;c=getchar();}
  21. while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
  22. return x*f;
  23. }
  24. void ins(int u,int v){e[++cnt]=(edge){v,first[u]};first[u]=cnt;}
  25. void dfs(int x)
  26. {
  27. in[x]=++ind;
  28. for(int i=;(<<i)<=deep[x];i++)
  29. fa[x][i]=fa[fa[x][i-]][i-];
  30. for(int i=first[x];i;i=e[i].next)
  31. {
  32. deep[e[i].to]=deep[x]+;
  33. dfs(e[i].to);
  34. }
  35. out[x]=ind;
  36. }
  37. int lca(int x,int y)
  38. {
  39. if(deep[x]<deep[y])swap(x,y);
  40. int d=deep[x]-deep[y];
  41. for(int i=;(<<i)<=d;i++)
  42. if((<<i)&d)x=fa[x][i];
  43. if(x==y)return x;
  44. for(int i=;i>=;i--)
  45. if((<<i)<=deep[x]&&fa[x][i]!=fa[y][i])
  46. x=fa[x][i],y=fa[y][i];
  47. return fa[x][];
  48. }
  49. void dfslow(int x)
  50. {
  51. for(int i=first[x];i;i=e[i].next)
  52. {
  53. int to=e[i].to;dfslow(to);
  54. if(deep[low[to][]]<deep[low[x][]])
  55. low[x][]=low[to][];
  56. }
  57. }
  58. int find(int x,int t)
  59. {
  60. if(deep[low[x][]]>deep[t]){val=-inf;return -;}
  61. if(x==t){val=-;return ;}
  62. val=;
  63. for(int i=;i>=;i--)
  64. if(deep[low[x][i]]>deep[t])
  65. x=low[x][i],val|=(<<i);
  66. return x;
  67. }
  68. int lowbit(int x){return x&(-x);}
  69. void add(int x,int v){for(;x<=n;x+=lowbit(x))tr[x]+=v;}
  70. int query(int x){int ans=;for(;x;x-=lowbit(x))ans+=tr[x];return ans;}
  71. void work(int x)
  72. {
  73. for(int sz=b[x].size(),i=;i<sz;i++)
  74. {
  75. int t=b[x][i];
  76. last[t]=query(out[q[t].y])-query(in[q[t].y]-);
  77. }
  78. for(int sz=a[x].size(),i=;i<sz;i++)add(in[a[x][i]],);
  79. for(int i=first[x];i;i=e[i].next)work(e[i].to);
  80. for(int sz=b[x].size(),i=;i<sz;i++)
  81. {
  82. int t=b[x][i];
  83. if(query(out[q[t].y])-query(in[q[t].y]-)!=last[t])ok[t]=true;
  84. }
  85. }
  86. int main()
  87. {
  88. n=read();
  89. for(int i=;i<=n;i++)
  90. fa[i][]=read(),ins(fa[i][],i);
  91. dfs();
  92. for(int i=;i<=n;i++)low[i][]=i;
  93. m=read();
  94. for(int i=;i<=m;i++)
  95. {
  96. c[i].x=read();c[i].y=read();
  97. c[i].t=lca(c[i].x,c[i].y);
  98. if(deep[c[i].t]<deep[low[c[i].x][]])
  99. low[c[i].x][]=c[i].t;
  100. if(deep[c[i].t]<deep[low[c[i].y][]])
  101. low[c[i].y][]=c[i].t;
  102. a[c[i].x].push_back(c[i].y);
  103. a[c[i].y].push_back(c[i].x);
  104. }
  105. dfslow();
  106. for(int t=;t<=n;t++)
  107. for(int i=;i<=;i++)
  108. low[t][i]=low[low[t][i-]][i-];
  109. Q=read();
  110. for(int i=;i<=Q;i++)
  111. {
  112. q[i].x=read();q[i].y=read();
  113. q[i].t=lca(q[i].x,q[i].y);
  114. ans[i]=;
  115. x=find(q[i].x,q[i].t);ans[i]+=val;
  116. y=find(q[i].y,q[i].t);ans[i]+=val;
  117. if(x>&&y>)
  118. {
  119. q[i].x=x;q[i].y=y;
  120. b[x].push_back(i);
  121. }
  122. }
  123. work();
  124. for(int i=;i<=Q;i++)
  125. if(ok[i])ans[i]--;
  126. for(int i=;i<=Q;i++)
  127. printf("%d\n",ans[i]<?-:ans[i]);
  128. return ;
  129. }

【codeforces 983E】NN country的更多相关文章

  1. 【codeforces 415D】Mashmokh and ACM(普通dp)

    [codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...

  2. 【codeforces 370C】Mittens

    [题目链接]:http://codeforces.com/problemset/problem/370/C [题意] 给你n个人,每个人都有一双相同颜色的手套; 然允许在所有人之间交换手套; (每个人 ...

  3. 【42.07%】【codeforces 558A】Lala Land and Apple Trees

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. 【codeforces 546E】Soldier and Traveling

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  5. 【codeforces 752F】Santa Clauses and a Soccer Championship

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  6. 【27.66%】【codeforces 592D】Super M

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  7. 【codeforces 761B】Dasha and friends

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  8. 【codeforces 762B】USB vs. PS/2

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. 【codeforces div3】【E. Cyclic Components】

    E. Cyclic Components time limit per test 2 seconds memory limit per test 256 megabytes input standar ...

随机推荐

  1. qt5.7.1 (create4.2.0)+msvc2015 安装后无法编译 & 缺少h文件

    其实问题的本质是,系统中没有vs2015的注册信息导致 一开始是报: "'cl' 不是内部或外部命令,也不是可运行的程序"解决方案 通过在环境变量中添加了C:\Program Fi ...

  2. Fiddler分享

    链接:https://pan.baidu.com/s/162YmGb7-aUZ6xDf8eRfgpw  密码:j6er

  3. vue源码分析—Vue.js 源码目录设计

    Vue.js 的源码都在 src 目录下,其目录结构如下 src ├── compiler # 编译相关 ├── core # 核心代码 ├── platforms # 不同平台的支持 ├── ser ...

  4. jupyter notebook修改默认路径和浏览器

    1.jupyter notebook --generate-config 2.修改jupyter_notebook_config.py配置文件 3.修改默认路径: c.NotebookApp.note ...

  5. Cookie Session和自定义分页

    cookie Cookie的由来 大家都知道HTTP协议是无状态的. 无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不 ...

  6. win10x64 批处理自动安装打印机

    系统版本:Windows 10企业版 64位(10.0 ,版本17134)- 中文(简体) 话不多说,直接上脚本: REM 提升管理员权限 @echo off chcp 65001 >nul s ...

  7. PHP 高级工程面试题汇总

    PHP高级工程面试题汇总(2018.05) 1.给你四个坐标点,判断它们能不能组成一个矩形,如判断([0,0],[0,1],[1,1],[1,0])能组成一个矩形. 勾股定理,矩形是对角线相等的四边形 ...

  8. 判定你的java应用是否正常(是否内存、线程泄漏)的一个简单方法

    给大家推荐一个最简单的判定你的java应用是否正常的方法: step1:部署你的应用,让它跑起来: step2:打开jdk下bin目录下的jconsole.exe工具,连接到你的应用——以监测线程和内 ...

  9. MySQL中怎么对varchar类型排序问题(转)

    在mysql默认order by 只对数字与日期类型可以排序,但对于varchar字符型类型排序好像没有用了,下面我来给各位同学介绍varchar类型排序问题如何解决.   今天在对国家电话号码表进行 ...

  10. SpringBoot自动装配源码解析

    序:众所周知spring-boot入门容易精通难,说到底spring-boot是对spring已有的各种技术的整合封装,因为封装了所以使用简单,也因为封装了所以越来越多的"拿来主义" ...