我亲爱的学姐冒险跑去为我们送正解

但是,,,,

阿龙粗现了!

cao,,

 Problem A.  最近公共祖先 ———2019.10.12 

考场期望得分:20   实际得分:20

Problem A. 最近公共祖先 (commonants.c/cpp/pas)
Problem A.  最近公共祖先 ———2019.10.12

 

 

 最近公共祖先(Lowest Common Ancestor,LCA)是指在一个树中同时拥有给定的两个点作为后

代的最深的节点。
为了学习最近公共祖先,你得到了一个层数为 n + 1 的满二叉树,其中根节点的深度为 0,其他
节点的深度为父节点的深度 +1 。你需要求出二叉树上所有点对 (i,j),(i,j 可以相等,也可以 i > j)
的最近公共祖先的深度之和对 10 9 + 7 取模后的结果。
Input
一行一个整数 n 。
Output
一行一个整数表示所有点对 (i,j),(i,j 可以相等,也可以 i > j)的最近公共祖先的深度之和对
10 9 + 7 取模后的结果。

Problem A.  最近公共祖先 ———2019.10.12

 

 

 


Notes
样例 1 解释:

Problem A.  最近公共祖先 ———2019.10.12

 

 

 


树一共有 7 个节点(一个根节点和两个子节点) ,其中 (4,4),(5,5),(6,6),(7,7) 共 4 对的最近公共
祖先深度为 2,(4,2),(2,4),(5,2),(2,5),(5,4),(4,5),(2,2),(6,3),(3,6),(3,7),(7,3),(6,7),(7,6),(3,3) 共 14 对最
近公共祖先深度是 1 ,其他的点对最近公共祖先深度为 0 ,所以答案为 22 。


Problem A.  最近公共祖先 ———2019.10.12

 

 

 

思路呢,,大概就是这样的:

算法1:

N<=10

直接暴力求树上两点的LCA

期望得分:20

(大概就是我的那20分吧)

代码~:

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<iostream>
 4 using namespace std;
 5 int n;
 6 const int mod=1e9+7;
 7 int deep[10000];
 8 long long ans;
 9 void dfs(int  i,long long t) {
10     if(i>n) return;
11     deep[t]=i;
12     dfs(i+1,t*2),dfs(i+1,t*2+1);
13 }
14 long long lca(long long i,long long j) {
15     while(1) {
16         if(i==j)break;
17         if(i<j)swap(i,j);
18         i/=2;
19     }
20     return deep[i];
21 }
22 long long tot;
23 int main() {
24     freopen("commonants.in","r",stdin);
25     freopen("commonants.out","w",stdout);
26     cin>>n;
27     tot=pow(2,n+1)-1;
28     dfs(0,1);
29     for(int i=1; i<=tot; i++)
30         for(int j=1; j<=tot; j++) {
31             int k=lca(i,j);
32             ans+=k;
33             ans%=mod;
34         }
35     cout<<ans;
36     fclose stdin;
37     fclose stdout;
38     return 0;
39 }
View Code

相关文章:

  • 2021-09-08
  • 2021-07-19
  • 2021-09-25
  • 2022-02-02
  • 2021-10-17
  • 2021-08-02
猜你喜欢
  • 2021-11-16
  • 2021-11-11
相关资源
相似解决方案