cf 832D Misha, Grisha and Underground 【lca+倍增】
来源:互联网 发布:mx anywhere2 软件 编辑:程序博客网 时间:2024/06/07 06:51
点击打开链接
题意:
给你一个树,再给你三个点,然后问你任意两个点到另外一个点中间经过的相同的节点最大个数。
题解:
照题解上面,求出任意两个点的公共祖先,保留深度最大的那一个。该点即为三个点的交汇点。
然后求出交汇点到三点的最大距离即为答案。
下面附上官方题解:
Let vertex 1 be the root of the tree. For each vertex i we calculate value hi — distance to the root.
Now we can represent way v1 v2 as two ways v1 lca(v1, v2) and lca(v1, v2) v2.
Note that number of edges in the interseption of two such ways v1 v2 и u1 u2, hv1 ≤ hv2, hu1 ≤ hu2 is max(0, hlca(u2, v2) - max(hv1, hu1)). We can calculate lca in O(log n), using binary lifting, or in O(1), using .
Using the formula we can easy calculate answer for fixed s, f and t. To answer the query, we consider all possible permutations of a, band c, there are only 3!.
Final asymptotics is O(n · log n + q · log n) or O(n + q), depending on the lca search algorithm.
#include <bits/stdc++.h>#define ll long longusing namespace std;const int maxn=1e5+10;const int DEG=20;const int mod=1e9+7;const ll inf=1e17;int n,q;struct node{ int to,nxt;}edge[maxn*2];int head[maxn],cnt=0;void addedge(int u,int v){ edge[cnt].to=v; edge[cnt].nxt=head[u]; head[u]=cnt++;}int fa[maxn][DEG];int deg[maxn],vis[maxn];void bfs(int root){ queue<int>que; deg[root]=0; fa[root][0]=root; que.push(root); while(!que.empty()){ int tmp=que.front(); que.pop(); for(int i=1;i<DEG;++i) fa[tmp][i]=fa[fa[tmp][i-1]][i-1]; for(int i=head[tmp];i!=-1;i=edge[i].nxt){ int v=edge[i].to; if(v==fa[tmp][0]) continue; deg[v]=deg[tmp]+1; fa[v][0]=tmp; que.push(v); } }}int LCA(int u,int v){ if(deg[u]>deg[v]) swap(u,v); int hu=deg[u],hv=deg[v]; int tu=u,tv=v; for(int det=hv-hu,i=0;det;det>>=1,i++) if(det&1) tv=fa[tv][i]; if(tu==tv) return tu; for(int i=DEG-1;i>=0;--i){ if(fa[tu][i]==fa[tv][i]) continue; tu=fa[tu][i]; tv=fa[tv][i]; } return fa[tu][0];}int dis(int u,int v){ return deg[u]+deg[v]-2*deg[LCA(u,v)];}int main(){ int x; memset(head,-1,sizeof(head)); scanf("%d %d",&n,&q); for(int i=2;i<=n;++i){ scanf("%d",&x); addedge(i,x); addedge(x,i); vis[i]++; vis[x]++; } int root; for(int i=1;i<=n;++i) if(vis[i]==1){ root=i; break; } bfs(root); int a,b,c; while(q--){ scanf("%d %d %d",&a,&b,&c); int r1=LCA(a,b); int r2=LCA(b,c); int r3=LCA(a,c); if(deg[r2]>deg[r1]) r1=r2; if(deg[r3]>deg[r1]) r1=r3; int ans=max(dis(r1,a),max(dis(r1,b),dis(r1,c))); printf("%d\n",ans+1); } return 0;}
- cf 832D Misha, Grisha and Underground 【lca+倍增】
- 【Lca 倍增】codeforces 832D Misha, Grisha and Underground
- codeforces 832D Misha, Grisha and Underground 倍增lca
- CF 832D Misha, Grisha and Underground(Tree+lca)
- CF --- 832D Misha, Grisha and Underground 【LCA + 思维】
- D. Misha, Grisha and Underground(LCA 倍增)
- CF #425 DIV2 D. Misha, Grisha and Underground(LCA)
- Codeforces 832 D. Misha, Grisha and Underground 倍增法求LCA
- codeforces 832 D Misha, Grisha and Underground(倍增)
- 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】
- 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
- hive数据仓库笔记
- Android打印工具类
- EventBus详解---参考官网
- input 上传图片显示预览、调用摄像头,ios和Android的兼容性解决
- 时域、频域、空间域
- cf 832D Misha, Grisha and Underground 【lca+倍增】
- POJ3648 A Simple Problem with Integers(树状数组实现)
- Android 系统发送“系统当前时间”的广播
- Selenium Grid 的使用
- 小白笔记-----------------------Metasploit (from tools)整理
- 【bzoj3522】 [Poi2014]Hotel
- Netty echo server 简例
- 奇偶位交换
- Mr.Smile填坑记——debug、release包MD5签名的获取方式