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

📅  最后修改于: 2021-04-29 01:31:16             🧑  作者: Mango

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

例子:

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的最大值的所有值使用动态编程和答案的预计算

  • 首先,请注意,如果路径的按位与是奇数,则该路径的任何元素都不能是偶数。因此,所需的路径应具有奇数个元素。
  • 我们知道,对于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


输出:
1
0

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