Description

The company \(X\) has \(n\) employees numbered from \(1\) through \(n\). Each employee \(u\) has a direct boss \(p_u\) \((1 \le p_u \le n)\), except for the employee \(1\) who has no boss. It is guaranteed, that values \(p_i\) form a tree. Employee \(u\) is said to be in charge of employee \(v\) if \(u\) is the direct boss of \(v\) or there is an employee \(w\) such that \(w\) is in charge of \(v\) and \(u\) is the direct boss of \(w\). Also, any employee is considered to be in charge of himself.

In addition, for each employee \(u\) we define it's level \(lv(u)\) as follow:

  • \(lv(1)=0\)
  • \(lv(u)=lv(p_u)+1\) for \(u \neq 1\)

In the near future, there are \(q\) possible plans for the company to operate. The \(i\)-th plan consists of two integers \(l_i\) and \(r_i\), meaning that all the employees in the range \([l_i,r_i]\), and only they, are involved in this plan. To operate the plan smoothly, there must be a project manager who is an employee in charge of all the involved employees. To be precise, if an employee \(u\) is chosen as the project manager for the \(i\)-th plan then for every employee \(v \in [l_i,r_i]\), \(u\) must be in charge of \(v\). Note, that \(u\) is not necessary in the range \([l_i,r_i]\). Also, \(u\) is always chosen in such a way that \(lv(u)\) is as large as possible (the higher the level is, the lower the salary that the company has to pay the employee).

Before any plan is operated, the company has JATC take a look at their plans. After a glance, he tells the company that for every plan, it's possible to reduce the number of the involved employees exactly by one without affecting the plan. Being greedy, the company asks JATC which employee they should kick out of the plan so that the level of the project manager required is as large as possible. JATC has already figured out the answer and challenges you to do the same.

Input

The first line contains two integers \(n\) and \(q\) \((2 \le n \le 100000, 1 \le q \le 100000)\) — the number of employees and the number of plans, respectively.

The second line contains \(n−1\) integers \(p_2,p_3,…,p_n(1≤p_i≤n)\) meaning \(p_{i}\) is the direct boss of employee \(i\).

It is guaranteed, that values \(p_{i}\) form a directed tree with the root of \(1\).

Each of the following \(q\) lines contains two integers \(l_i\) and \(r_i\) \((1 \le l_i < r_i \le n)\) — the range of the employees, involved in the corresponding plan.

Output

Print \(q\) lines, each containing two integers — the number of the employee which should be kicked from the corresponding plan and the maximum possible level of the project manager in that case.

If there are more than one way to choose that employee, print any of them.

Example

Input

11 5
1 1 3 3 3 4 2 7 7 6
4 6
4 8
1 11
9 11
8 11

Output

4 1
8 1
1 0
11 3
8 1

Note

In the example:

In the first query, we can choose whether \(4\) or \(5\) or \(6\) and the project manager will be \(3\).

In the second query, if we choose any employee other than the employee \(8\), the project manager will be \(1\). If we choose \(8\), the project manager will be \(3\). Since \(lv(3)=1 \gt lv(1)=0\), choosing \(8\) is the best strategy.

In the third query, no matter how we choose the employee, the project manager will always be \(1\).

In the fourth query, if we choose \(9\) or \(10\) then the project manager will be \(3\). If we choose \(11\) then the project manager will be \(7\). Since \(lv(7)=3 \gt lv(3)=1\), we choose \(11\) as the answer.

Solution

题意:给一棵树,\(n\)个点,\(q\)次询问,每次询问给定一个区间\([l, r]\),要求忽略掉\([l, r]\)中的一个点,使得剩下的$r - l $个点的LCA的深度最大,问应该忽略哪个点,忽略后的最大深度是多少。

首先求一次DFS序,对于任意点\(u\),其DFS序记为\(order[u]\)。给定区间\([l, r]\),设其中DFS序最大和最小的点分别为\(u\)和\(v\),则\(LCA[l, r]\)就是\(LCA(u, v)\)。我们可以简单证明一下,不妨设\(r = LCA(u, v)\),点\(x\)不属于以\(r\)为根的子树(记作\(SubTree(r)\))当且仅当\(order[x]\)满足以下两种情况中的一种:

  • \(order[x] \lt order[r]​\),即\(x​\)在\(r​\)之前被访问
  • \(order[x] > order[i], \forall i \in SubTree(r)\),即\(x\)在\(SubTree(r)\)之后才被访问

显然,\([l, r]\)中的任何一个点都不满足上述两个条件,所以\([l, r]\)中的每个点都属于以\(r\)为根的子树,所以它们的LCA就是\(r\)。

回到我们的问题,对于每次询问,给定\([l, r]\),我们先求出其中DFS序最大、最小的点\(u, v\)以及它们的LCA \(r\)。显然,忽略\(u\)和\(v\)之外的节点对并不会改变LCA;如果忽略\(u\),那么新的LCA就是\(LCA[l, u-1]\)和\(LCA[u + 1, r]\)的LCA,我们称之为\(r_1\);同理,忽略\(v\)也可以得到一个新的LCA,我们称之为\(r_2\)。选择\(r, r_1, r_2\)中深度最大的点,我们就得到了答案。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100011;
const int maxp = 18;
vector<int> w[maxn];
int idx, dfsod[maxn], invdfsod[maxn];
int fa[maxn][maxp], dep[maxn];
void bfs(int root) {
queue<int> que;
dep[root] = 0;
fa[root][0] = root;
que.push(root);
while (!que.empty()) {
int u = que.front();
que.pop();
for (int i = 1; i < maxp; i++)
fa[u][i] = fa[fa[u][i - 1]][i - 1];
for (int v : w[u]) {
if (v == fa[u][0]) continue;
dep[v] = dep[u] + 1;
fa[v][0] = u;
que.push(v);
}
}
}
int lca(int u, int v) {
if (dep[u] > dep[v])
swap(u, v);
for (int gap = dep[v] - dep[u], i = 0; gap; gap >>= 1, i++) {
if (gap & 1)
v = fa[v][i];
}
if (u == v) return u;
for (int i = maxp - 1; i >= 0; i--) {
if (fa[u][i] == fa[v][i])
continue;
u = fa[u][i], v = fa[v][i];
}
return fa[u][0];
}
void dfs(int u, int pre = -1) {
dfsod[u] = ++idx;
invdfsod[idx] = u;
for (int v : w[u]) {
if (v == pre) continue;
dfs(v, u);
}
}
struct node {
int l, r, mx, mn;
} seg[maxn << 2];
void pushup(int x) {
seg[x].mx = max(seg[x << 1].mx, seg[x << 1 | 1].mx);
seg[x].mn = min(seg[x << 1].mn, seg[x << 1 | 1].mn);
}
void build(int x, int l, int r) {
seg[x].l = l, seg[x].r = r;
if (l == r) {
seg[x].mx = seg[x].mn = dfsod[l];
return;
}
int m = (l + r) >> 1;
build(x << 1, l, m);
build(x << 1 | 1, m + 1, r);
pushup(x);
}
pair<int, int> query(int x, int l, int r) {
int L = seg[x].l, R = seg[x].r;
if (l <= L && r >= R)
return make_pair(seg[x].mn, seg[x].mx);
int m = (L + R) >> 1;
int mx = 0, mn = 1 << 30;
if (l <= m) {
auto v = query(x << 1, l, r);
mn = min(mn, v.first);
mx = max(mx, v.second);
}
if (r > m) {
auto v = query(x << 1 | 1, l, r);
mn = min(mn, v.first);
mx = max(mx, v.second);
}
return make_pair(mn, mx);
}
// 区间[l, r]的LCA
int getlca(int l, int r) {
if (l > r) return -1;
auto x = query(1, l, r);
int u = invdfsod[x.first], v = invdfsod[x.second];
return lca(u, v);
}
// 忽略u后,区间[l, r]的LCA
int getlca(int l, int r, int u) {
int a = getlca(l, u - 1), b = getlca(u + 1, r);
if (a == -1) return b;
if (b == -1) return a;
return lca(a, b);
}
int main() {
int n, q;
scanf("%d%d", &n, &q);
for (int i = 2; i <= n; ++i) {
int x; scanf("%d", &x);
w[x].push_back(i);
w[i].push_back(x);
}
bfs(1);
dfs(1);
build(1, 1, n);
dep[0] = -1;
while (q--) {
int l, r;
scanf("%d%d", &l, &r);
auto x = query(1, l, r);
int u = invdfsod[x.first], v = invdfsod[x.second];
int c = lca(u, v), a = getlca(l, r, u), b = getlca(l, r, v);
int mx = max(dep[c], max(dep[a], dep[b])), y;
if (mx == dep[c]) y = l;
else if (mx == dep[a]) y = u;
else y = v;
printf("%d %d\n", y, mx);
}
return 0;
}

CodeForces 1062E Company的更多相关文章

  1. Codeforces 1090A - Company Merging - [签到水题][2018-2019 Russia Open High School Programming Contest Problem A]

    题目链接:https://codeforces.com/contest/1090/problem/A A conglomerate consists of n companies. To make m ...

  2. Codeforces 1062E 题解

    给出一棵有根树,1为根结点,接下来q次询问,每次给出一个[l,r]区间,现在允许删掉[l,r]区间内任何一个点,使得所有点的最近公共祖先的深度尽可能大,问删掉的点是哪个点,深度最大是多少. 做法: 线 ...

  3. CodeForces 1025G Company Acquisitions

    题意 描述有点麻烦,就不写了. \(\texttt{Data Range:}1\leq n\leq 500\) 题解 势能函数这个东西好神啊-- 这个题目用常规的 DP 好像做不出来,所以我们可以考虑 ...

  4. Codeforces 556D Restructuring Company

    传送门 D. Restructuring Company time limit per test 2 seconds memory limit per test 256 megabytes input ...

  5. Codeforces Round #321 (Div. 2) B. Kefa and Company 二分

    B. Kefa and Company Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/580/pr ...

  6. [刷题]Codeforces 794C - Naming Company

    http://codeforces.com/contest/794/problem/C Description Oleg the client and Igor the analyst are goo ...

  7. CodeForces 125E MST Company

    E. MST Company time limit per test 8 seconds memory limit per test 256 megabytes input standard inpu ...

  8. Codeforces 1062 E - Company

    E - Company 思路: 首先,求出每个点的dfs序 然后求一些点的公共lca, 就是求lca(u, v), 其中u是dfs序最大的点, v是dfs序最小的大点 证明: 假设o是这些点的公共lc ...

  9. Codeforces Round #520 (Div. 2) E. Company(dfs序判断v是否在u的子树里+lca+线段树)

    https://codeforces.com/contest/1062/problem/E 题意 给一颗树n,然后q个询问,询问编号l~r的点,假设可以删除一个点,使得他们的最近公共祖先深度最大.每次 ...

随机推荐

  1. [翻译] DBCamera 轻量级定制摄像头

    DBCamera 轻量级定制摄像头 https://github.com/danielebogo/DBCamera DBCamera is a simple custom camera with AV ...

  2. Oracle数据库突然宕机,处理方案

    一.现象 数据库突然断掉,无法响应,. 二.分析 查看日志发现错误如下(日志路径:D:\app\Administrator\diag\rdbms\orcl\orcl\trace\alert_hrpde ...

  3. 铁乐学python_Day41_线程01

    线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运行,而这种执行的程序就称之为进程. 程序和进程的区别就在于: 程序是 ...

  4. September 27th 2017 Week 39th Wednesday

    We both look up at the same stars, yet we see such different things. 我们仰望同一片星空,却看见了不同的事物. Looking up ...

  5. September 10th 2017 Week 37th Sunday

    Dream most deep place, only then the smile is not tired. 梦的最深处,只有微笑不累. Everyday I expect I can go to ...

  6. python decorator的本质

    推荐查看博客:python的修饰器 对于Python的这个@注解语法糖- Syntactic Sugar 来说,当你在用某个@decorator来修饰某个函数func时,如下所示: @decorato ...

  7. 20145203JAVA课程总结

    20145203盖泽双 <Java程序设计>课程总结 课程总结 (按顺序)每周读书笔记链接汇总 调查问卷:http://www.cnblogs.com/GZSdeboke/p/524832 ...

  8. 集合之Stack

    在Java中Stack类表示后进先出(LIFO)的对象堆栈.栈是一种非常常见的数据结构,它采用典型的先进后出的操作方式完成的.每一个栈都包含一个栈顶,每次出栈是将栈顶的数据取出,如下: Stack通过 ...

  9. 多线程之Lock

    Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized来实现同步访问.本文我们继续来探讨这个问题,从Java 5之后,在java.util.concurrent.l ...

  10. Java反射学习二

    利用反射进行对象拷贝的例子 如下例程ReflectTester类进一步演示了Reflection API的基本使用方法. ReflectTester类有一个copy(Object object)方法, ...