📌  相关文章
📜  给定二叉树中的路径计数,对于 Q 查询具有奇数位 AND

📅  最后修改于: 2021-09-22 09:46:37             🧑  作者: Mango

给定一个表示查询数量的整数 Q和一个数组,其中每个查询都有一个整数N 。我们的任务是遍历每个查询并找到路径数,使得该路径上所有节点的按位 AND 为奇数。

例子:

Input: Q = 2, [5, 2]
Output: 1 0
Explanation: 
For first query the binary tree will be 
        1
      /   \ 
     2     3
   /   \
  4     5
The path which satisfies
the condition is 1 -> 3.
Hence only 1 path.
For the second query,
the binary tree will be 
        1
       /
      2 
There no such path that
satisfies the condition.

Input: Q = 3, [3, 7, 13]
Output: 1 3 4 

方法:想法是对查询中从 1 到 N 的最大值的所有值使用动态规划和预计算答案。

  • 首先,观察如果路径的按位 AND 是奇数,则该路径的任何元素都不能是偶数。因此,所需的路径应该有奇数元素。
  • 我们知道对于i节点(节点 1 除外),父节点将为 i/2(四舍五入)。维护一个dp 数组,用于存储第 i节点的答案。另一个数组将用于存储从当前节点到父节点为奇数的奇数元素的数量。
  • 在计算 dp 数组时,第一个条件是如果第 i节点的值是偶数,则dp[i] = dp[i – 1]因为第 i节点对答案没有贡献,因此 dp[i] 将为第 (i-1)节点的答案。其次,如果i节点是奇数,则 dp[i] = dp[i-1] + nC2 -(n-1)C2。简化后dp[i] = dp[i-1] +(到现在为止的奇数元素数)– 1。

下面是上述方法的实现:

C++
// C++ implementation to count
// paths in Binary Tree
// with odd bitwise AND
 
#include 
using namespace std;
 
// Function to count number of paths
// in binary tree such that bitwise
// AND of all nodes is Odd
void compute(vector query)
{
    // vector v for storing
    // the count of odd numbers
 
    // vector dp to store the
    // count of bitwise odd paths
    // till that vertex
    vector v(100001), dp(100001);
 
    v[1] = 1, v[2] = 0;
    dp[1] = 0, dp[2] = 0;
 
    // Precomputing for each value
    for (int i = 3; i < 100001; i++) {
        // check for odd value
        if (i % 2 != 0) {
            if ((i / 2) % 2 == 0) {
                v[i] = 1;
                dp[i] = dp[i - 1];
            }
 
            else {
                // Number of odd elements will
                // be +1 till the parent node
                v[i] = v[i / 2] + 1;
                dp[i] = dp[i - 1] + v[i] - 1;
            }
        }
 
        // For even case
        else {
            // Since node is even
            // Number of odd elements
            // will be 0
            v[i] = 0;
 
            // Even value node will
            // not contribute in answer
            // hence dp[i] = previous answer
            dp[i] = dp[i - 1];
        }
    }
    // Printing the answer
    // for each query
    for (auto x : query)
        cout << dp[x] << endl;
}
 
// Driver code
int main()
{
    // vector to store queries
    vector query = { 5, 2 };
    compute(query);
    return 0;
}


Java
// Java implementation to count
// paths in Binary Tree
// with odd bitwise AND
class GFG{
 
// Function to count number of paths
// in binary tree such that bitwise
// AND of all nodes is Odd
static void compute(int[] query)
{
     
    // v for storing the count
    // of odd numbers
 
    // dp to store the count of
    // bitwise odd paths
    // till that vertex
    int []v = new int[100001];
    int []dp = new int[100001];
     
    v[1] = 1; v[2] = 0;
    dp[1] = 0; dp[2] = 0;
 
    // Precomputing for each value
    for(int i = 3; i < 100001; i++)
    {
         
       // Check for odd value
       if (i % 2 != 0)
       {
           if ((i / 2) % 2 == 0)
           {
               v[i] = 1;
               dp[i] = dp[i - 1];
           }
           else
           {
                
               // Number of odd elements will
               // be +1 till the parent node
               v[i] = v[i / 2] + 1;
               dp[i] = dp[i - 1] + v[i] - 1;
           }
       }
        
       // For even case
       else
       {
            
           // Since node is even
           // Number of odd elements
           // will be 0
           v[i] = 0;
            
           // Even value node will
           // not contribute in answer
           // hence dp[i] = previous answer
           dp[i] = dp[i - 1];
       }
    }
     
    // Printing the answer
    // for each query
    for(int x : query)
       System.out.print(dp[x] + "\n");
}
 
// Driver code
public static void main(String[] args)
{
     
    // To store queries
    int []query = { 5, 2 };
     
    compute(query);
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 implementation to count
# paths in Binary Tree with odd
# bitwise AND
 
# Function to count number of paths
# in binary tree such that bitwise
# AND of all nodes is Odd
def compute(query):
     
    # vector v for storing
    # the count of odd numbers
 
    # vector dp to store the
    # count of bitwise odd paths
    # till that vertex
    v = [None] * 100001
    dp = [None] * 100001
 
    v[1] = 1
    v[2] = 0
    dp[1] = 0
    dp[2] = 0
 
    # Precomputing for each value
    for i in range(3, 100001):
         
        # Check for odd value
        if (i % 2 != 0):
            if ((i // 2) % 2 == 0):
                v[i] = 1
                dp[i] = dp[i - 1]
 
            else:
                 
                # Number of odd elements will
                # be +1 till the parent node
                v[i] = v[i // 2] + 1
                dp[i] = dp[i - 1] + v[i] - 1
 
        # For even case
        else:
             
            # Since node is even
            # Number of odd elements
            # will be 0
            v[i] = 0
 
            # Even value node will
            # not contribute in answer
            # hence dp[i] = previous answer
            dp[i] = dp[i - 1]
 
    # Printing the answer
    # for each query
    for x in query:
        print(dp[x])
 
# Driver code
 
# Vector to store queries
query = [ 5, 2 ]
 
compute(query)
 
# This code is contributed by sanjoy_62


C#
// C# implementation to count
// paths in Binary Tree
// with odd bitwise AND
using System;
 
class GFG{
 
// Function to count number of paths
// in binary tree such that bitwise
// AND of all nodes is Odd
static void compute(int[] query)
{
     
    // v for storing the count
    // of odd numbers
 
    // dp to store the count of
    // bitwise odd paths
    // till that vertex
    int []v = new int[100001];
    int []dp = new int[100001];
     
    v[1] = 1; v[2] = 0;
    dp[1] = 0; dp[2] = 0;
 
    // Precomputing for each value
    for(int i = 3; i < 100001; i++)
    {
         
        // Check for odd value
        if (i % 2 != 0)
        {
            if ((i / 2) % 2 == 0)
            {
                v[i] = 1;
                dp[i] = dp[i - 1];
            }
            else
            {
                     
                // Number of odd elements will
                // be +1 till the parent node
                v[i] = v[i / 2] + 1;
                dp[i] = dp[i - 1] + v[i] - 1;
            }
        }
         
        // For even case
        else
        {
                 
            // Since node is even
            // Number of odd elements
            // will be 0
            v[i] = 0;
                 
            // Even value node will
            // not contribute in answer
            // hence dp[i] = previous answer
            dp[i] = dp[i - 1];
        }
    }
     
    // Printing the answer
    // for each query
    foreach(int x in query)
    Console.Write(dp[x] + "\n");
}
 
// Driver code
public static void Main(String[] args)
{
     
    // To store queries
    int []query = { 5, 2 };
     
    compute(query);
}
}
 
// This code is contributed by Amit Katiyar


Javascript


输出:
1
0

时间复杂度: O( Nmax + Q*(1) ) ,其中 Nmax 是 N 的最大值。 Q*(1) 因为我们正在预先计算每个查询。