Misha, Grisha and Underground CodeForces - 832D (倍增树上求LCA)
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 a, b 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 s, f, t 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 a, b 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 s, t and f are chosen optimally from the three stations on the i-th day.
Examples
3 2
1 1
1 2 3
2 3 3
2
3
4 1
1 2 3
1 2 3
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分别做为交点的路径情况的最大值即是答案。
细节见代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
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;}
inline void getInt(int* p);
const int maxn=;
const int inf=0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
const int N = 1e5+;
std::vector<int> son[N];
int depth[N],fa[N][],in[N],a,b;
// depth[i] -> i 节点的深度
// fa[i][j] -> i 节点向上移动2^j个节点后的祖先
// fa[i][0] -> i 向上移动1个节点后的祖先,即父节点
// in[i] i节点的入度,用来找树根用的。
// a b 为读边用的。
int n;
int m;
void buildtree()
{
for(int i=;i<=n;i++)
{
a=i;
scanf("%d",&b);
son[a].push_back(b);
son[b].push_back(a);
}
}
void dfs(int rt,int prev)
{
depth[rt]=depth[prev]+;
fa[rt][]=prev;
for(int i=;i<;i++)
{
fa[rt][i]=fa[fa[rt][i-]][i-];
}
for(int i=;i<son[rt].size();i++)
{
if(son[rt][i]==prev)
continue;
dfs(son[rt][i],rt);
}
}
int LCA(int x,int y)
{
if(depth[x]<depth[y])
swap(x,y);
for(int i=;i>=;i--)
{
if(depth[x]-(<<i)>=depth[y])
{
x=fa[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=;i>=;i--)
{
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
}
return fa[x][];
}
int dist(int a,int b)
{
int u=LCA(a,b);
int L=depth[a]+depth[b]-*depth[u];
return L;
}
int main()
{
// freopen("C:\\Users\\DH_M\\Desktop\\code_io\\in.txt.txt","r",stdin);
// freopen("C:\\Users\\DH_M\\Desktop\\code_io\\out.txt.txt","w",stdout);
scanf("%d",&n);
scanf("%d",&m);
buildtree();
depth[]=-;
int rt=;// root
dfs(rt,rt);
int c;
for(int i=;i<=m;i++)
{
scanf("%d %d %d",&a,&b,&c);
int ans=;
int lab,lbc,lac,l1,l2,l3;
lac=dist(a,c);
lab=dist(a,b);
lbc=dist(b,c);
l1=(lab+lbc-lac)/;
l2=(lab+lac-lbc)/;
l3=(lac+lbc-lab)/;
ans=max(l1,max(l2,l3));
printf("%d\n",ans+);
}
return ;
} inline void getInt(int* p) {char ch;do {ch = getchar();}
while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '');
while ((ch = getchar()) >= '' && ch <= '') {*p = *p * - ch + '';}}
else {*p = ch - '';while ((ch = getchar()) >= '' && ch <= '')
{*p = *p * + ch - '';}}}
Misha, Grisha and Underground CodeForces - 832D (倍增树上求LCA)的更多相关文章
- 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 ...
- Codeforces 832D - Misha, Grisha and Underground
832D - Misha, Grisha and Underground 思路:lca,求两个最短路的公共长度.公共长度公式为(d(a,b)+d(b,c)-d(a,c))/2. 代码: #includ ...
- 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 ...
- Codeforces 832 D Misha, Grisha and Underground
Misha, Grisha and Underground 题意:Misha 和 Grisha 是2个很喜欢恶作剧的孩子, 每天早上 Misha 会从地铁站 s 通过最短的路到达地铁站 f, 并且在每 ...
- 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 ...
- D. Misha, Grisha and Underground 树链剖分
D. Misha, Grisha and Underground 这个题目算一个树链剖分的裸题,但是这个时间复杂度注意优化. 这个题目可以选择树剖+线段树,时间复杂度有点高,比较这个本身就有n*log ...
- 倍增法求lca(最近公共祖先)
倍增法求lca(最近公共祖先) 基本上每篇博客都会有参考文章,一是弥补不足,二是这本身也是我学习过程中找到的觉得好的资料 思路: 大致上算法的思路是这样发展来的. 想到求两个结点的最小公共祖先,我们可 ...
- HDU 2586 倍增法求lca
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- 倍增法求LCA
倍增法求LCA LCA(Least Common Ancestors)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可 ...
随机推荐
- 内核线程的进程描述符task_struct中的mm和active_mm
task_struct进程描述符中包含两个跟进程地址空间相关的字段mm, active_mm, struct task_struct { // ... struct mm_struct *mm; st ...
- c/c++ const this指针
const this指针 方法列表后面的const是什么含义呢?答案:不可以在方法里修改成员变量 class Test{ public: void fun()const{ //data = 10;// ...
- Linux系统中Redis和Tomcat的PID文件路径设置
Tomcat: /bin/catalina.sh 文件头注释下面添加一行:CATALINA_PID=/var/run/tomcat.pid Redis: redis.conf配置文件里面搜索pidfi ...
- 阿里云短信服务调用例子-Python
阿里云短信服务调用例子 阿里云官方文档https://helpcdn.aliyun.com/document_detail/101893.html 首先需要安装阿里云PythonSDK(下面是pyth ...
- openPose-注
静态编译出错:MD能通过 \ https://blog.csdn.net/Silver_sail/article/details/40540887 E:\project\BodyPoseEstimat ...
- 关于Three.js基本几何形状
一.有关球体SphereGeometry构造函数参数说明 SphereGeometry(radius, widthSegments, heightSegments, phiStart, phiLeng ...
- 【Teradata】gtwglobal查看
使用root登录TD数据库节点 cnsterm 6 start gtwglobal cnsterm 3 //上一个命令的window编号 h //帮助 QUIT //退出
- 强化学习(一)—— 基本概念及马尔科夫决策过程(MDP)
1.策略与环境模型 强化学习是继监督学习和无监督学习之后的第三种机器学习方法.强化学习的整个过程如下图所示: 具体的过程可以分解为三个步骤: 1)根据当前的状态 $s_t$ 选择要执行的动作 $ a_ ...
- 【转】解决在Android设备播放音频与其他应用重音的问题,并监听耳机的控制按钮
概述 在安卓开发中免不了需要播放一点音乐了,音频了.但是这时候有别的应用正在播放,这时候就会出现重音的现象,完全影响用户体验,我们的项目就遇上了这样的尴尬,然后查找了一些文档,记录一下: 管理音频焦点 ...
- Python中关于if __name__=='__main__'的问题
先举一个简单的例子: 这里有两个.py的文件,a.py和b.py a.py内容为: b.py的内容为: 当执行b.py时结果为: 也就是将a.py文件里的内容执行一边,b.py里的内容执行一边,这显然 ...