Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations connected with n - 1 routes so that each route connects two stations, and it is possible to reach every station from any other.

The boys decided to have fun and came up with a plan. Namely, in some day in the morning Misha will ride the underground from station s to station f by the shortest path, and will draw with aerosol an ugly text "Misha was here" on every station he will pass through (including s and f). After that on the same day at evening Grisha will ride from station t to station f by the shortest path and will count stations with Misha's text. After that at night the underground workers will wash the texts out, because the underground should be clean.

The boys have already chosen three stations ab and c for each of several following days, one of them should be station s on that day, another should be station f, and the remaining should be station t. They became interested how they should choose these stations sft so that the number Grisha will count is as large as possible. They asked you for help.

Input

The first line contains two integers n and q (2 ≤ n ≤ 105, 1 ≤ q ≤ 105) — the number of stations and the number of days.

The second line contains n - 1 integers p2, p3, ..., pn (1 ≤ pi ≤ n). The integer pimeans that there is a route between stations pi and i. It is guaranteed that it's possible to reach every station from any other.

The next q lines contains three integers ab and c each (1 ≤ a, b, c ≤ n) — the ids of stations chosen by boys for some day. Note that some of these ids could be same.

Output

Print q lines. In the i-th of these lines print the maximum possible number Grisha can get counting when the stations st and f are chosen optimally from the three stations on the i-th day.

Examples

Input
  1. 3 2
    1 1
    1 2 3
    2 3 3
Output
  1. 2
    3
Input
  1. 4 1
    1 2 3
    1 2 3
Output
  1. 2

Note

In the first example on the first day if s = 1, f = 2, t = 3, Misha would go on the route 1  2, and Grisha would go on the route 3  1  2. He would see the text at the stations 1 and 2. On the second day, if s = 3, f = 2, t = 3, both boys would go on the route 3  1  2. Grisha would see the text at 3 stations.

In the second examle if s = 1, f = 3, t = 2, Misha would go on the route 1  2 3, and Grisha would go on the route 2  3 and would see the text at both stations.

题意:给定一个含有N个节点的树,和Q个群问,每一个询问包括三个整数,a,b,c 。 让求出这三个整数构成的两个路径中交点个数的最大值。

思路:

首先我们应该知道这样的问题,如果这三个整数构成了这样的两个路径,a到b,和,c到b  这两个路径。

定义a到b的距离是lab,其他类推。那么这两个路径的交点个数是 ( lab + lbc - lac ) / 2 + 1

那么我们用倍增在线LCA求任意两个节点的最短路径的距离,然后枚举a,b,c分别做为交点的路径情况的最大值即是答案。

细节见代码:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <queue>
  7. #include <stack>
  8. #include <map>
  9. #include <set>
  10. #include <vector>
  11. #include <iomanip>
  12. #define ALL(x) (x).begin(), (x).end()
  13. #define dll(x) scanf("%I64d",&x)
  14. #define xll(x) printf("%I64d\n",x)
  15. #define sz(a) int(a.size())
  16. #define all(a) a.begin(), a.end()
  17. #define rep(i,x,n) for(int i=x;i<n;i++)
  18. #define repd(i,x,n) for(int i=x;i<=n;i++)
  19. #define pii pair<int,int>
  20. #define pll pair<long long ,long long>
  21. #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
  22. #define MS0(X) memset((X), 0, sizeof((X)))
  23. #define MSC0(X) memset((X), '\0', sizeof((X)))
  24. #define pb push_back
  25. #define mp make_pair
  26. #define fi first
  27. #define se second
  28. #define eps 1e-6
  29. #define gg(x) getInt(&x)
  30. #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
  31. using namespace std;
  32. typedef long long ll;
  33. ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
  34. ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
  35. ll powmod(ll a,ll b,ll MOD){ll ans=1ll;while(b){if(b&)ans=ans*a%MOD;a=a*a%MOD;b>>=;}return ans;}
  36. inline void getInt(int* p);
  37. const int maxn=;
  38. const int inf=0x3f3f3f3f;
  39. /*** TEMPLATE CODE * * STARTS HERE ***/
  40. const int N = 1e5+;
  41. std::vector<int> son[N];
  42. int depth[N],fa[N][],in[N],a,b;
  43. // depth[i] -> i 节点的深度
  44. // fa[i][j] -> i 节点向上移动2^j个节点后的祖先
  45. // fa[i][0] -> i 向上移动1个节点后的祖先,即父节点
  46. // in[i] i节点的入度,用来找树根用的。
  47. // a b 为读边用的。
  48. int n;
  49. int m;
  50. void buildtree()
  51. {
  52. for(int i=;i<=n;i++)
  53. {
  54. a=i;
  55. scanf("%d",&b);
  56. son[a].push_back(b);
  57. son[b].push_back(a);
  58. }
  59. }
  60. void dfs(int rt,int prev)
  61. {
  62. depth[rt]=depth[prev]+;
  63. fa[rt][]=prev;
  64. for(int i=;i<;i++)
  65. {
  66. fa[rt][i]=fa[fa[rt][i-]][i-];
  67. }
  68. for(int i=;i<son[rt].size();i++)
  69. {
  70. if(son[rt][i]==prev)
  71. continue;
  72. dfs(son[rt][i],rt);
  73. }
  74. }
  75. int LCA(int x,int y)
  76. {
  77. if(depth[x]<depth[y])
  78. swap(x,y);
  79. for(int i=;i>=;i--)
  80. {
  81. if(depth[x]-(<<i)>=depth[y])
  82. {
  83. x=fa[x][i];
  84. }
  85. }
  86. if(x==y)
  87. {
  88. return x;
  89. }
  90. for(int i=;i>=;i--)
  91. {
  92. if(fa[x][i]!=fa[y][i])
  93. {
  94. x=fa[x][i];
  95. y=fa[y][i];
  96. }
  97. }
  98. return fa[x][];
  99. }
  100. int dist(int a,int b)
  101. {
  102. int u=LCA(a,b);
  103. int L=depth[a]+depth[b]-*depth[u];
  104. return L;
  105. }
  106. int main()
  107. {
  108. // freopen("C:\\Users\\DH_M\\Desktop\\code_io\\in.txt.txt","r",stdin);
  109. // freopen("C:\\Users\\DH_M\\Desktop\\code_io\\out.txt.txt","w",stdout);
  110. scanf("%d",&n);
  111. scanf("%d",&m);
  112. buildtree();
  113. depth[]=-;
  114. int rt=;// root
  115. dfs(rt,rt);
  116. int c;
  117. for(int i=;i<=m;i++)
  118. {
  119. scanf("%d %d %d",&a,&b,&c);
  120. int ans=;
  121. int lab,lbc,lac,l1,l2,l3;
  122. lac=dist(a,c);
  123. lab=dist(a,b);
  124. lbc=dist(b,c);
  125. l1=(lab+lbc-lac)/;
  126. l2=(lab+lac-lbc)/;
  127. l3=(lac+lbc-lab)/;
  128. ans=max(l1,max(l2,l3));
  129. printf("%d\n",ans+);
  130. }
  131. return ;
  132. }
  133.  
  134. inline void getInt(int* p) {char ch;do {ch = getchar();}
  135. while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '');
  136. while ((ch = getchar()) >= '' && ch <= '') {*p = *p * - ch + '';}}
  137. else {*p = ch - '';while ((ch = getchar()) >= '' && ch <= '')
  138. {*p = *p * + ch - '';}}}

Misha, Grisha and Underground CodeForces - 832D (倍增树上求LCA)的更多相关文章

  1. Codeforces Round #425 (Div. 2) Problem D Misha, Grisha and Underground (Codeforces 832D) - 树链剖分 - 树状数组

    Misha and Grisha are funny boys, so they like to use new underground. The underground has n stations ...

  2. Codeforces 832D - Misha, Grisha and Underground

    832D - Misha, Grisha and Underground 思路:lca,求两个最短路的公共长度.公共长度公式为(d(a,b)+d(b,c)-d(a,c))/2. 代码: #includ ...

  3. Codeforces Round #425 (Div. 2) Misha, Grisha and Underground(LCA)

    Misha, Grisha and Underground time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  4. Codeforces 832 D Misha, Grisha and Underground

    Misha, Grisha and Underground 题意:Misha 和 Grisha 是2个很喜欢恶作剧的孩子, 每天早上 Misha 会从地铁站 s 通过最短的路到达地铁站 f, 并且在每 ...

  5. Codeforecs Round #425 D Misha, Grisha and Underground (倍增LCA)

    D. Misha, Grisha and Underground time limit per test 2 seconds memory limit per test 256 megabytes i ...

  6. D. Misha, Grisha and Underground 树链剖分

    D. Misha, Grisha and Underground 这个题目算一个树链剖分的裸题,但是这个时间复杂度注意优化. 这个题目可以选择树剖+线段树,时间复杂度有点高,比较这个本身就有n*log ...

  7. 倍增法求lca(最近公共祖先)

    倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可 ...

  8. HDU 2586 倍增法求lca

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  9. 倍增法求LCA

    倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可 ...

随机推荐

  1. 反射生成 INSERT 多个对象的 SQL 语句(批量插入)

    + View code private static void insertObject(List<?> objectList) throws IllegalAccessException ...

  2. Android Studio连接天天模拟器

    方法:安装两者后,打开天天模拟器的adb.exe所在目录,我的是C:\Users\ Android\sdk\platform-tools,在打开的文件夹下使用“shift+鼠标右键”打开cmd终端. ...

  3. CVE-2012-0158 分析

    目录 CVE-2012-0158 分析&利用 1.实验环境 2.下载poc样本 3.调试并找到漏洞触发点 4.分析漏洞触发模块及流程 5.漏洞利用 6.总结 7.参考资料 CVE-2012-0 ...

  4. MATLAB求解二重积分案例

    凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 定积分解决的是一维连续量求和的问题,而解决多维连续量的求和问题就要用到重积分了.重积分是建立在定积分的基础上的 ...

  5. LDAP概念

    1.1.LDAP目录结构   此图为树形目录结构,我将此跳过去了,因为这个是按照“国家这种结构来划分的”.如果你喜欢这样看更好,如下还有一种: 树也可以根据互联网域名组主.这种命名方式正越来越受欢迎, ...

  6. request.getParameter("name")乱码问题

    1 页面提交http的get请求时,找到页面的字符编码<%@ page contentType="text/html;charset=utf-8" language=&quo ...

  7. SpringBoot注册登录(三):注册--验证账号密码是否符合格式及后台完成注册功能

    SpringBoot注册登录(一):User表的设计点击打开链接SpringBoot注册登录(二):注册---验证码kaptcha的实现点击打开链接      SpringBoot注册登录(三):注册 ...

  8. 关于connect by rownum与connect by leve

    http://www.itpub.net/forum.php?mod=viewthread&tid=1570306 http://www.itpub.net/forum.php?mod=vie ...

  9. 转://【MOS】关于在不同版本和平台之间进行还原或复制的常见问题 (文档 ID 1526162.1)--跨版本恢复

    Questions and Answers 1) 我能用更高版本的 Oracle 还原或复制旧版本的数据库吗? 2) 我能在两个不同的补丁程序集之间进行还原或复制吗? 3) 我能在同一操作系统的不同版 ...

  10. 邮票面值设计 (动态规划+DFS)

    题意:https://ac.nowcoder.com/acm/problem/16813 思路: 深度搜索:每一层枚举一个面值,然后通过dp进行检查,并通过已知面值得到最多n张得到的最大表示数. 其实 ...