codeforces 832 D Misha, Grisha and Underground(倍增)
来源:互联网 发布:好搜小说软件 编辑:程序博客网 时间:2024/06/15 02:37
题意:
给出n个点的树,q个询问,每次询问给出3个数x,y,z问选两个点作为起点,到第三个点的路径有多少个点重合。
解题 思路:
distance(x,y)=distance(x,root)+distance(y, root)-2*distance(lca(x,y),root).
x,y为起点时,答案就是(dis(x,z)+dis(y,z)-dis(x,y))/2 。
重点讲一下倍增吧,第一次写,求LCA简直不能更简单。
倍增顾明思义就是成倍增大。两个点往上找lca的时候就是一个每次往上的距离成倍变大的一个过程。
倍增求LCA需要预处理祖先数组。fa[i][j],表示第i个点的第2^j个祖先,j从0开始。
这个处理起始非常简单,fa[i][j]=fa[fa[i][j-1][i].因为第2^j个祖先等价于当前点第2^(j-1)个祖先的第2^(j-1)个祖先,一次跑一遍就可以了。
另外还需要处理处每个点的深度,这个简单,必要的话要处理下到根节点的距离,没有边权的时候其实就是深度。
求a和b的lca的时候,先让深度大的节点先往上跳,跳的过程可以用二进制优化,设深度差为dif,把dif二进制拆分,只需要对为1的对应位j跳到第2^j个祖先就可以。
当深度一样时,判断下当前是否a和b是否相等,不相等让a和b同时往上跳,j从高到低判断下第2^j个祖先是否相同,相同就不往上跳,知道碰到祖先不同再往上跳。循环结束后,a和b的父亲就是lca了。
代码:
#include <bits/stdc++.h>#define ps push_backusing namespace std;const int maxn=1e5+5;int dp[maxn][22];int dep[maxn];vector<int>edg[maxn];void dfs(int x, int fa){ dep[x]=dep[fa]+1; int v; if(fa) for(int i=1; i<20; i++) { dp[x][i]=dp[dp[x][i-1]][i-1]; } for(int i=0; i<(int)edg[x].size(); i++) { v=edg[x][i]; if(v==fa)continue; dp[v][0]=x; dfs(v, x); } return;}int dis(int a, int b){ int x=a, y=b; if(dep[a]<dep[b]) { swap(a,b); } int i, dif=dep[a]-dep[b]; for(i=0; (1<<i)<=dif; i++) { if(dif&(1<<i)) { a=dp[a][i]; } } if(a==b) { return dep[x]+dep[y]-2*dep[a]; } for(i=20; i>=0 && a!=b; i--) { if(dp[a][i]==dp[b][i])continue; a=dp[a][i]; b=dp[b][i]; } a=dp[a][0]; return dep[x]+dep[y]-2*dep[a];}int query(int x, int y, int z){// printf("%d %d %d\n", dis(x, z), dis(y, z), dis(x, y)); return (dis(x, z)+dis(y, z)-dis(x, y))/2;}int main(){ int n, x, q, i, j; cin>>n>>q; for(i=2; i<=n; i++) { scanf("%d", &x); edg[x].ps(i); } dp[1][0]=1; dep[1]=1; dfs(1, 0);// for(i=1; i<=3; i++)printf("%d\n", dp[i][0]); int y, z; for(i=1; i<=q; i++) { scanf("%d%d%d", &x, &y, &z); printf("%d\n", max(max(query(x, y, z), query(x, z, y)), query(z, y, x))+1); }}
阅读全文
0 0
- codeforces 832 D Misha, Grisha and Underground(倍增)
- 【Lca 倍增】codeforces 832D Misha, Grisha and Underground
- codeforces 832D Misha, Grisha and Underground 倍增lca
- codeforces 832D Misha, Grisha and Underground
- Codeforces 832D Misha, Grisha and Underground
- [codeforces 832D]Misha, Grisha and Underground
- 【Codeforces】832D. Misha, Grisha and Underground
- Codeforces-832D-Misha, Grisha and Underground
- cf 832D Misha, Grisha and Underground 【lca+倍增】
- D. Misha, Grisha and Underground(LCA 倍增)
- Codeforces 832 D. Misha, Grisha and Underground 倍增法求LCA
- codeforces D. Misha, Grisha and Underground(LCA)
- Codeforces 832D-Misha, Grisha and Underground(LCA)
- Codeforces 832D. Misha, Grisha and Underground【LCA】
- Codeforces 832D Misha, Grisha and Underground【LCA】
- CF 832D Misha, Grisha and Underground(Tree+lca)
- codeforces 832D——Misha, Grisha and Underground(LCA)
- Codeforces Round #425 (Div. 2)D. Misha, Grisha and Underground
- js选择结构
- PAT乙级 1062. 最简分数(20)--简单易错注意细节
- LingCode Range Sum Query 2D
- Android 双进程守护
- poj 1269 Intersecting Lines
- codeforces 832 D Misha, Grisha and Underground(倍增)
- java面试资料-基础知识
- Only call 'softmax_cross_entropy_with_logits' with named grguments(labels=...,logits=...)
- Java面试题:Servlet是线程安全的吗?
- springboot填坑之 -- spring cloud基于ip的discovery服务注册中心配置
- Spring整合Redis
- JavaScript js设计思维 if语句
- 动态规划——AGTC
- 运放的平衡电阻