LCA On N-ary Tree Problem Solution

The 4 questions before the training game of the Zhejiang University Chengyuan are water questions, which can be cut directly in 40 minutes. Then the question of LCA actually appeared in ICPC last time, it was a mock question. Now use the code of your teammates to learn

topic

Link: https://ac.nowcoder.com/acm/contest/12986/D
Source: Niuke.com

The N-ary tree is a tree that each node has exactly n child nodes.
You are given an N-ary tree with infinite nodes, each node is numbered from 1 to infinity according to the level order(from left to right, level by level).
Insert picture description here

                                        The first 13 nodes on the 3-ary tree.

Given the number x and y of the two nodes, you have to calculate the lowest common ancestors(LCA) of these two nodes.
Definition of the lowest common ancestors(LCA): The LCA of two nodes on the tree refers to the node is the ancestor of these two nodes with the shortest distance to these two nodes, it should be noted that the node itself is also considered its own ancestor. For example, on the 3-ary tree the LCA of node 6 and node 3 is node 1.

Insert picture description here

enter

4
1 2 3
2 4 6
3 6 3
10000 10000 10000

Output

2
1
1
10000

AC code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define pre(i,a,b) for(int i=a;i>=b;--i)
#define m(x) memset(x,0,sizeof x)
const double PI = acos(-1);
const int maxn = 1e6+5;
int a[1005], b[1005];
int main()
{
    
    
          int t;
          scanf("%d",&t);
          while(t--)
          {
    
    
              int n,x,y,xf;
              scanf("%d%d%d",&n,&x,&y);
              //特判
              if(n==1)
              {
    
    
                  printf("%d\n",min(x,y));
                  continue;
              }
              if(x==y)
              {
    
    
                  printf("%d\n",x);
                  continue;
              }
              
              //xf标记大数初始化,y标记小数
              int t=max(x,y);
              y=min(x,y);
              x=t;
              xf = x;
              
              while(xf>=y)
              {
    
    
                  if(x%n>1)xf=x/n+1;
                  else xf=x/n;//根据上文提供构建下层逻辑 求父节点
                  if(xf<=y)break;
                  x=xf;
              }
              
              //表示xf的父节点恰好是y
              if(xf==y)
              {
    
    
                  printf("%d\n",xf);
                  continue;
              }
              //在此只能保证x在y的下层或是同层 故逆序递推时应先更新x
              while(x!=y)
              {
    
    
                  if(x%n>1)x=x/n+1;
                  else x=x/n;
                  if(x==y)break;
                  if(y%n>1)y=y/n+1;
                  else y=y/n;
              }
              printf("%d\n",x);
          }
    return 0;
}


thought

The most important thing in this question is to build a tree. The question stipulates that it is an n-ary number. Let's simulate a few pictures.
Insert picture description here

We can find the following rules:
1. The unary tree is obviously a special judgment, the LCA of x and y is obviously min{x,y};
2. We can find a middle branch, and the value above is obviously n^a (a represents the number of layers, the position of 1 is layer 0)
3. The number of each layer is n^a, then the starting number of layer a can be inferred from layer 2 asInsert picture description here

Find the module of the upper node

 while(xf>=y)
{
    
    
 if(x%n>1)xf=x/n+1;
 else xf=x/n;//根据上文提供构建下层逻辑 求父节点
 if(xf<=y)break;
 x=xf;
}
//在此只能保证x在y的下层或是同层 故逆序递推时应先更新x
while(x!=y)
{
    
    
if(x%n>1)x=x/n+1;
else x=x/n;
if(x==y)break;
if(y%n>1)y=y/n+1;
else y=y/n;
}

Guess you like

Origin blog.csdn.net/DAVID3A/article/details/115176967