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)的意思是最近公共祖先,即在一棵树中,找出两节点最近的公共祖先. 倍增法是通过一个数组来实现直接找到一个节点的某个祖先,这样我们就可 ...
随机推荐
- sql server 的Maintenance Plans(维护计划)详解
下面说下我遇到的场景,就是我通过数据库自身的维护计划建立了数据库收缩自动计划,却发现数据库并没有实际性收缩. 前奏自动化配置流程 数据库--管理---维护计划--双击(维护计划向导)--下一步--名称 ...
- Linux CFS调度器之虚拟时钟vruntime与调度延迟--Linux进程的管理与调度(二十六)
1 虚拟运行时间(今日内容提醒) 1.1 虚拟运行时间的引入 CFS为了实现公平,必须惩罚当前正在运行的进程,以使那些正在等待的进程下次被调度. 具体实现时,CFS通过每个进程的虚拟运行时间(vrun ...
- LeetCode算法题-Best Time to Buy and Sell Stock II
这是悦乐书的第173次更新,第175篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第32题(顺位题号是122).假设有一个数组,其中第i个元素是第i天给定股票的价格.设计 ...
- Spring的AOP基于AspectJ的注解方式开发3
上上偏博客介绍了@Aspect,@Before 上篇博客介绍了spring的AOP开发的注解通知类型:@Before,@AfterThrowing,@After,@AfterReturning,@Ar ...
- 【Linux基础】history查看历史命令
1.history命令 “history”命令就是历史记录.它显示了在终端中所执行过的所有命令的历史. history //显示终端执行过的命令 history //显示最近10条终端执行过的命令 C ...
- 别老扯什么hadoop,你的数据根本不够大
本文原名“Don't use Hadoop when your data isn't that big ”,出自有着多年从业经验的数据科学家Chris Stucchio,纽约大学柯朗研究所博士后,搞过 ...
- 最小生成树 A - 畅通工程
dalao视频:https://www.bilibili.com/video/av4768483 https://www.bilibili.com/video/av4768483?p=2 省政府“畅通 ...
- 更改django的时区
TIME_ZONE='Asia/Shanghai' datetime_obj.replace(tzinfo=(pytz.timezone("Asia/Shanghai"))).st ...
- 十大PHP程序员必备工具
十大PHP程序员必备工具 1.Notepad++ 总结来说就是小而精,7.4版本的软件包只有2.9M,比一般的IDE小数十倍,但是Notepad++的功能确是很全面的,代码高亮,语法折叠,宏功能,内置 ...
- Gps定位和wifi定位和基站定位的比较
现在手机定位的方式是:Gps定位,wifi定位,基站定位 Gps定位的前提,手机开启Gps定位模块,在室外,定位的精度一般是几米的范围 wifi定位的前提,手机要开启wifi,连不连上wifi热点都可 ...