📌  相关文章
📜  在相邻对上执行交替的按位或运算和按位XOR运算后的剩余元素

📅  最后修改于: 2021-05-25 03:08:39             🧑  作者: Mango

给定一个由N个元素(始终为2的幂)组成的数组和Q个查询。
每个查询都由索引两个元素组成 。我们需要编写一个程序,该程序为A索引分配,并打印对每个查询执行以下操作后剩下的单个元素:

  • 在替代步骤中,对相邻元素执行按位或运算按位XOR运算。
  • 在第一次迭代选择中,选择从左向右移动的n / 2对,并对所有对值进行按位“或”运算。在第二次迭代中,选择(n / 2)/ 2个剩余对,并对它们进行按位XOR。在第三次迭代选择中,选择((n / 2)/ 2)/ 2个从左向右移动的剩余对,并对所有对值进行按位“或”运算。
  • 继续上述步骤,直到剩下单个元素为止。

例子:

Input : n = 4   m = 2 
        arr = [1, 4, 5, 6] 
        Queries- 
        1st: index=0 value=2  
        2nd: index=3 value=5
Output : 1 
         3 

Explanation: 

1st query: 

Assigning 2 to index 0, the sequence is now 
[2, 4, 5, 6]. 
1st iteration: There are 4/2=2 pairs (2, 4) and (5, 6) 
2 OR 4 gives 6, and 5 OR 6 gives us 7. So the 
sequence is now [6, 7]. 

2nd iteration: There is 1 pair left now (6, 7) 
6^7=1. 

Hence the last element left is 1 which is the 
answer to our first query. 

2nd Query: 

Assigning 5 to index 3, the sequence is now 
[2, 4, 5, 5]. 
1st iteration: There are 4/2=2 pairs (2, 4) and (5, 5) 
2 OR 4 gives 6, and 5 OR 5 gives us 5. So the 
sequence is now [6, 5]. 

2nd iteration: There is 1 pair left now (6, 5) 
6^5=3. 

Hence the last element left is 3 which is the
answer to our second query.

天真的方法:天真的方法是执行每个步骤,直到我们剩下一个元素为止。使用二维矢量,我们将存储每一步后剩余的结果元素。 V [steps-1] [0..size]给出上一步的元素数量。如果步数为奇数,则执行按位“或”运算,否则执行按位“异或”运算。重复这些步骤,直到剩下一个元素为止。剩下的最后一个要素将是我们的答案。
下面是幼稚方法的实现:

C++
// CPP program to print the Leftover element after
// performing alternate Bitwise OR and Bitwise XOR
// operations to the pairs.
#include 
using namespace std;
#define N 1000
 
int lastElement(int a[],int n)
{
    // count the step number
    int steps = 1;
    vectorv[N];
 
    // if one element is there, it will be the answer
    if (n==1) return a[0];
 
 
    // at first step we do a bitwise OR
    for (int i = 0 ; i < n ; i += 2)
        v[steps].push_back(a[i] | a[i+1]);
 
 
    // keep on doing bitwise operations till the
    // last element is left
    while (v[steps].size()>1)
    {
 
        steps += 1;
 
        // perform operations
        for (int i = 0 ; i < v[steps-1].size(); i+=2)
        {
            // if step is the odd step
            if (steps&1)
                v[steps].push_back(v[steps-1][i] | v[steps-1][i+1]);
            else  // even step
                v[steps].push_back(v[steps-1][i] ^ v[steps-1][i+1]);
        }
    }
 
    // answer when one element is left
    return v[steps][0];
}
 
// Driver Code
int main()
{
    int a[] = {1, 4, 5, 6};
    int n = sizeof(a)/sizeof(a[0]);
 
    // 1st query
    int index = 0;
    int value = 2;
    a[0] = 2;
    cout << lastElement(a,n) << endl;
 
    // 2nd query
    index = 3;
    value = 5;
    a[index] = value;
    cout << lastElement(a,n)  << endl;
 
    return 0;
}


Java
// Java program to print the Leftover element
// after performing alternate Bitwise OR and
// Bitwise XOR operations to the pairs.
import java.util.*;
 
class GFG
{
static int N = 1000;
 
static int lastElement(int a[], int n)
{
    // count the step number
    int steps = 1;
    Vector []v = new Vector[N];
    for (int i = 0; i < N; i++)
        v[i] = new Vector();
 
    // if one element is there,
    // it will be the answer
    if (n == 1) return a[0];
 
    // at first step we do a bitwise OR
    for (int i = 0 ; i < n ; i += 2)
        v[steps].add(a[i] | a[i + 1]);
 
    // keep on doing bitwise operations
    // till the last element is left
    while (v[steps].size() > 1)
    {
 
        steps += 1;
 
        // perform operations
        for (int i = 0; i < v[steps - 1].size(); i += 2)
        {
            // if step is the odd step
            if (steps % 2 == 1)
                v[steps].add(v[steps - 1].get(i) |
                             v[steps - 1].get(i + 1));
            else // even step
                v[steps].add(v[steps - 1].get(i) ^
                             v[steps - 1].get(i + 1));
        }
    }
 
    // answer when one element is left
    return v[steps].get(0);
}
 
// Driver Code
public static void main(String[] args)
{
    int a[] = {1, 4, 5, 6};
    int n = a.length;
 
    // 1st query
    int index = 0;
    int value = 2;
    a[0] = 2;
    System.out.println(lastElement(a, n));
 
    // 2nd query
    index = 3;
    value = 5;
    a[index] = value;
    System.out.println(lastElement(a, n));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to print the Leftover element
# after performing alternate Bitwise OR and
# Bitwise XOR operations to the pairs.
N = 1000
 
def lastElement(a, n):
  
    # count the step number
    steps = 1
    v = [[] for i in range(n)]
 
    # if one element is there, it will be the answer
    if n == 1: return a[0]
 
    # at first step we do a bitwise OR
    for i in range(0, n, 2):
        v[steps].append(a[i] | a[i+1])
 
    # keep on doing bitwise operations
    # till the last element is left
    while len(v[steps]) > 1:
     
        steps += 1
        # perform operations
        for i in range(0, len(v[steps-1]), 2):
          
            # if step is the odd step
            if steps & 1:
                v[steps].append(v[steps-1][i] | v[steps-1][i+1])
            else: # even step
                v[steps].append(v[steps-1][i] ^ v[steps-1][i+1])
          
    # answer when one element is left
    return v[steps][0]
 
# Driver Code
if __name__ == "__main__":
  
    a = [1, 4, 5, 6]
    n = len(a)
 
    # 1st query
    index, value, a[0] = 0, 2, 2
    print(lastElement(a,n))
 
    # 2nd query
    index, value = 3, 5
    value = 5
    a[index] = value
    print(lastElement(a,n))
  
# This code is contributed by Rituraj Jain


C#
// C# program to print the Leftover element
// after performing alternate Bitwise OR and
// Bitwise XOR operations to the pairs.
using System;
using System.Collections.Generic;
 
class GFG
{
static int N = 1000;
 
static int lastElement(int []a, int n)
{
    // count the step number
    int steps = 1;
    List []v = new List[N];
    for (int i = 0; i < N; i++)
        v[i] = new List();
 
    // if one element is there,
    // it will be the answer
    if (n == 1)
        return a[0];
 
    // at first step we do a bitwise OR
    for (int i = 0 ; i < n ; i += 2)
        v[steps].Add(a[i] | a[i + 1]);
 
    // keep on doing bitwise operations
    // till the last element is left
    while (v[steps].Count > 1)
    {
        steps += 1;
 
        // perform operations
        for (int i = 0; i < v[steps - 1].Count; i += 2)
        {
            // if step is the odd step
            if (steps % 2 == 1)
                v[steps].Add(v[steps - 1][i] |
                             v[steps - 1][i + 1]);
            else // even step
                v[steps].Add(v[steps - 1][i] ^
                             v[steps - 1][i + 1]);
        }
    }
 
    // answer when one element is left
    return v[steps][0];
}
 
// Driver Code
public static void Main(String[] args)
{
    int []a = {1, 4, 5, 6};
    int n = a.Length;
 
    // 1st query
    int index = 0;
    int value = 2;
    a[0] = 2;
    Console.WriteLine(lastElement(a, n));
 
    // 2nd query
    index = 3;
    value = 5;
    a[index] = value;
    Console.WriteLine(lastElement(a, n));
}
}
 
// This code is contributed by 29AjayKumar


Javascript


C++
// CPP program to print the Leftover element after
// performing alternate Bitwise OR and
// Bitwise XOR operations to the pairs.
#include 
using namespace std;
#define N 1000
 
// array to store the tree
int tree[N];
 
// array to store the level of every parent
int level[N];
 
// function to construct the tree
void constructTree(int low, int high, int pos, int a[])
{
    if (low == high)
    {
        // level of child is always 0
        level[pos] = 0;
        tree[pos] = a[high];
        return;
    }
    int mid = (low + high) / 2;
 
    // recursive call
    constructTree(low, mid, 2 * pos + 1, a);
    constructTree(mid + 1, high, 2 * pos + 2, a);
 
    // increase the level of every parent, which is
    // level of child + 1
    level[pos] = level[2 * pos + 1] + 1;
 
    // if the parent is at odd level, then do a
    // bitwise OR
    if (level[pos] & 1)
        tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2];
 
    // if the parent is at even level, then
    // do a bitwise XOR
    else
        tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2];
}
 
// function that updates the tree
void update(int low, int high, int pos, int index, int a[])
{
    // if it is a leaf and the leaf which is
    // to be updated
    if (low == high and low == index)
    {
        tree[pos] = a[low];
        return;
    }
 
    // out of range
    if (index < low || index > high)
        return;
 
    // not a leaf then recurse
    if (low != high)
    {
        int mid = (low + high) / 2;
 
        // recursive call
        update(low, mid, 2 * pos + 1, index, a);
        update(mid + 1, high, 2 * pos + 2, index, a);
 
        // check if the parent is at odd or even level
        // and perform OR or XOR according to that
        if (level[pos] & 1)
            tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2];
        else
            tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2];
    }
}
 
// function that assigns value to a[index]
// and calls update function to update the tree
void updateValue(int index, int value, int a[], int n)
{
    a[index] = value;
    update(0, n - 1, 0, index, a);
}
 
// Driver Code
int main()
{
    int a[] = { 1, 4, 5, 6 };
    int n = sizeof(a) / sizeof(a[0]);
 
    // builds the tree
    constructTree(0, n - 1, 0, a);
 
    // 1st query
    int index = 0;
    int value = 2;
    updateValue(index, value, a, n);
    cout << tree[0] << endl;
 
    // 2nd query
    index = 3;
    value = 5;
    updateValue(index, value, a, n);
    cout << tree[0] << endl;
 
    return 0;
}


Java
// java program to print the Leftover
// element after performing alternate
// Bitwise OR and Bitwise XOR operations
// to the pairs.
import java .io.*;
 
public class GFG {
 
    static int N = 1000;
     
    // array to store the tree
    static int []tree = new int[N];
     
    // array to store the level of
    // every parent
    static int []level = new int[N];
     
    // function to construct the tree
    static void constructTree(int low, int high,
                               int pos, int []a)
    {
        if (low == high)
        {
             
            // level of child is
            // always 0
            level[pos] = 0;
            tree[pos] = a[high];
            return;
        }
        int mid = (low + high) / 2;
     
        // recursive call
        constructTree(low, mid, 2 * pos + 1, a);
         
        constructTree(mid + 1, high,
                                2 * pos + 2, a);
     
        // increase the level of every parent,
        // which is level of child + 1
        level[pos] = level[2 * pos + 1] + 1;
     
        // if the parent is at odd level, then
        // do a bitwise OR
        if ((level[pos] & 1) > 0)
            tree[pos] = tree[2 * pos + 1] |
                              tree[2 * pos + 2];
     
        // if the parent is at even level, then
        // do a bitwise XOR
        else
            tree[pos] = tree[2 * pos + 1] ^
                              tree[2 * pos + 2];
    }
     
    // function that updates the tree
    static void update(int low, int high, int pos,
                               int index, int []a)
    {
         
        // if it is a leaf and the leaf which is
        // to be updated
        if (low == high && low == index)
        {
            tree[pos] = a[low];
            return;
        }
     
        // out of range
        if (index < low || index > high)
            return;
     
        // not a leaf then recurse
        if (low != high)
        {
            int mid = (low + high) / 2;
     
            // recursive call
            update(low, mid, 2 * pos + 1, index, a);
             
            update(mid + 1, high, 2 * pos + 2,
                                          index, a);
     
            // check if the parent is at odd or
            // even level and perform OR or XOR
            // according to that
            if ((level[pos] & 1) > 0)
                tree[pos] = tree[2 * pos + 1] |
                                  tree[2 * pos + 2];
            else
                tree[pos] = tree[2 * pos + 1] ^
                                  tree[2 * pos + 2];
        }
    }
     
    // function that assigns value to a[index]
    // and calls update function to update the
    // tree
    static void updateValue(int index, int value,
                                   int []a, int n)
    {
        a[index] = value;
        update(0, n - 1, 0, index, a);
    }
     
    // Driver Code
    static public void main (String[] args)
    {
        int []a = { 1, 4, 5, 6 };
        int n = a.length;;
     
        // builds the tree
        constructTree(0, n - 1, 0, a);
     
        // 1st query
        int index = 0;
        int value = 2;
        updateValue(index, value, a, n);
        System.out.println(tree[0]);
     
        // 2nd query
        index = 3;
        value = 5;
        updateValue(index, value, a, n);
        System.out.println(tree[0]);
    }
}
 
// This code is contributed by vt_m.


Python3
# Python3 program to print the Leftover element
# after performing alternate Bitwise OR and
# Bitwise XOR operations to the pairs.
N = 1000
 
# array to store the tree
tree = [None] * N
 
# array to store the level of every parent
level = [None] * N
 
# function to construct the tree
def constructTree(low, high, pos, a):
  
    if low == high:
      
        # level of child is always 0
        level[pos], tree[pos] = 0, a[high]
        return
      
    mid = (low + high) // 2
 
    # Recursive call
    constructTree(low, mid, 2 * pos + 1, a)
    constructTree(mid + 1, high, 2 * pos + 2, a)
 
    # Increase the level of every parent,
    # which is level of child + 1
    level[pos] = level[2 * pos + 1] + 1
 
    # If the parent is at odd level,
    # then do a bitwise OR
    if level[pos] & 1:
        tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2]
 
    # If the parent is at even level,
    # then do a bitwise XOR
    else:
        tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2]
  
# Function that updates the tree
def update(low, high, pos, index, a):
  
    # If it is a leaf and the leaf
    # which is to be updated
    if low == high and low == index:
      
        tree[pos] = a[low]
        return
      
    # out of range
    if index < low or index > high:
        return
 
    # not a leaf then recurse
    if low != high:
      
        mid = (low + high) // 2
 
        # recursive call
        update(low, mid, 2 * pos + 1, index, a)
        update(mid + 1, high, 2 * pos + 2, index, a)
 
        # check if the parent is at odd or even level
        # and perform OR or XOR according to that
        if level[pos] & 1:
            tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2]
        else:
            tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2]
 
# Function that assigns value to a[index]
# and calls update function to update the tree
def updateValue(index, value, a, n):
  
    a[index] = value
    update(0, n - 1, 0, index, a)
  
# Driver Code
if __name__ == "__main__":
  
    a = [1, 4, 5, 6]
    n = len(a)
 
    # builds the tree
    constructTree(0, n - 1, 0, a)
 
    # 1st query
    index, value = 0, 2
    updateValue(index, value, a, n)
    print(tree[0])
 
    # 2nd query
    index, value = 3, 5
    updateValue(index, value, a, n)
    print(tree[0])
  
# This code is contributed by Rituraj Jain


C#
// C# program to print the Leftover
// element after performing alternate
// Bitwise OR and Bitwise XOR
// operations to the pairs.
using System;
 
public class GFG {
 
    static int N = 1000;
     
    // array to store the tree
    static int []tree = new int[N];
     
    // array to store the level of
    // every parent
    static int []level = new int[N];
     
    // function to construct the
    // tree
    static void constructTree(int low, int high,
                               int pos, int []a)
    {
        if (low == high)
        {
             
            // level of child is always 0
            level[pos] = 0;
            tree[pos] = a[high];
            return;
        }
        int mid = (low + high) / 2;
     
        // recursive call
        constructTree(low, mid, 2 * pos + 1, a);
         
        constructTree(mid + 1, high,
                                2 * pos + 2, a);
     
        // increase the level of every parent,
        // which is level of child + 1
        level[pos] = level[2 * pos + 1] + 1;
     
        // if the parent is at odd level,
        // then do a bitwise OR
        if ((level[pos] & 1) > 0)
            tree[pos] = tree[2 * pos + 1] |
                           tree[2 * pos + 2];
     
        // if the parent is at even level,
        // then do a bitwise XOR
        else
            tree[pos] = tree[2 * pos + 1] ^
                          tree[2 * pos + 2];
    }
     
    // function that updates the tree
    static void update(int low, int high,
               int pos, int index, int []a)
    {
         
        // if it is a leaf and the leaf
        // which is to be updated
        if (low == high && low == index)
        {
            tree[pos] = a[low];
            return;
        }
     
        // out of range
        if (index < low || index > high)
            return;
     
        // not a leaf then recurse
        if (low != high)
        {
            int mid = (low + high) / 2;
     
            // recursive call
            update(low, mid, 2 * pos + 1,
                                   index, a);
                                    
            update(mid + 1, high, 2 * pos + 2,
                                    index, a);
     
            // check if the parent is at odd
            // or even level and perform OR
            // or XOR according to that
            if ((level[pos] & 1) > 0)
                tree[pos] = tree[2 * pos + 1] |
                              tree[2 * pos + 2];
            else
                tree[pos] = tree[2 * pos + 1]
                            ^ tree[2 * pos + 2];
        }
    }
     
    // function that assigns value to a[index]
    // and calls update function to update
    // the tree
    static void updateValue(int index, int value,
                                 int []a, int n)
    {
        a[index] = value;
        update(0, n - 1, 0, index, a);
    }
     
    // Driver Code
    static public void Main ()
    {
        int []a = { 1, 4, 5, 6 };
        int n = a.Length;;
     
        // builds the tree
        constructTree(0, n - 1, 0, a);
     
        // 1st query
        int index = 0;
        int value = 2;
        updateValue(index, value, a, n);
        Console.WriteLine(tree[0]);
     
        // 2nd query
        index = 3;
        value = 5;
        updateValue(index, value, a, n);
        Console.WriteLine(tree[0]);
    }
}
 
// This code is contributed by vt_m.


输出:

1
3

时间复杂度: O(N * 2 N )
高效方法:高效方法是使用细分树。以下是用于解决该问题的完整分段树方法。

建树

段树的叶子将存储数组值,其父树将存储叶子的OR。父级在树中向上移动,每隔一步,父级存储左子级和右子级的按位XOR或按位OR。在每个奇数迭代中,我们执行对的按位“或”运算,类似地,在每个偶数运算中执行对的按位“异或”运算。因此,奇数双亲将存储左右子代的按位或。类似地,偶数双亲存储左和右子级的按位XOR。 level []是一个数组,存储从1开始的每个父级的级别,以确定其下面的对(右子对和左子对)是执行OR运算还是XOR运算。树的根将是我们在每次更新操作后对给定序列的答案。


上图说明了如果序列为[1、2、3、4、5、6、7、8]时树的构造,那么经过3次迭代,我们将剩下12个作为答案并存储在树中在根。

回答查询

无需重建完整的树即可执行更新操作。要进行更新,我们应该找到从根到相应叶路径,并仅在位于找到的路径上的父级处重新计算值。
父母等级:
在树上使用DP,我们可以轻松存储每个父级的级别。将叶节点级别初始化为0,并在向上移动到每个父级时继续添加。
用于计算父级的递归关系为:

下面是上述方法的实现:

C++

// CPP program to print the Leftover element after
// performing alternate Bitwise OR and
// Bitwise XOR operations to the pairs.
#include 
using namespace std;
#define N 1000
 
// array to store the tree
int tree[N];
 
// array to store the level of every parent
int level[N];
 
// function to construct the tree
void constructTree(int low, int high, int pos, int a[])
{
    if (low == high)
    {
        // level of child is always 0
        level[pos] = 0;
        tree[pos] = a[high];
        return;
    }
    int mid = (low + high) / 2;
 
    // recursive call
    constructTree(low, mid, 2 * pos + 1, a);
    constructTree(mid + 1, high, 2 * pos + 2, a);
 
    // increase the level of every parent, which is
    // level of child + 1
    level[pos] = level[2 * pos + 1] + 1;
 
    // if the parent is at odd level, then do a
    // bitwise OR
    if (level[pos] & 1)
        tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2];
 
    // if the parent is at even level, then
    // do a bitwise XOR
    else
        tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2];
}
 
// function that updates the tree
void update(int low, int high, int pos, int index, int a[])
{
    // if it is a leaf and the leaf which is
    // to be updated
    if (low == high and low == index)
    {
        tree[pos] = a[low];
        return;
    }
 
    // out of range
    if (index < low || index > high)
        return;
 
    // not a leaf then recurse
    if (low != high)
    {
        int mid = (low + high) / 2;
 
        // recursive call
        update(low, mid, 2 * pos + 1, index, a);
        update(mid + 1, high, 2 * pos + 2, index, a);
 
        // check if the parent is at odd or even level
        // and perform OR or XOR according to that
        if (level[pos] & 1)
            tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2];
        else
            tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2];
    }
}
 
// function that assigns value to a[index]
// and calls update function to update the tree
void updateValue(int index, int value, int a[], int n)
{
    a[index] = value;
    update(0, n - 1, 0, index, a);
}
 
// Driver Code
int main()
{
    int a[] = { 1, 4, 5, 6 };
    int n = sizeof(a) / sizeof(a[0]);
 
    // builds the tree
    constructTree(0, n - 1, 0, a);
 
    // 1st query
    int index = 0;
    int value = 2;
    updateValue(index, value, a, n);
    cout << tree[0] << endl;
 
    // 2nd query
    index = 3;
    value = 5;
    updateValue(index, value, a, n);
    cout << tree[0] << endl;
 
    return 0;
}

Java

// java program to print the Leftover
// element after performing alternate
// Bitwise OR and Bitwise XOR operations
// to the pairs.
import java .io.*;
 
public class GFG {
 
    static int N = 1000;
     
    // array to store the tree
    static int []tree = new int[N];
     
    // array to store the level of
    // every parent
    static int []level = new int[N];
     
    // function to construct the tree
    static void constructTree(int low, int high,
                               int pos, int []a)
    {
        if (low == high)
        {
             
            // level of child is
            // always 0
            level[pos] = 0;
            tree[pos] = a[high];
            return;
        }
        int mid = (low + high) / 2;
     
        // recursive call
        constructTree(low, mid, 2 * pos + 1, a);
         
        constructTree(mid + 1, high,
                                2 * pos + 2, a);
     
        // increase the level of every parent,
        // which is level of child + 1
        level[pos] = level[2 * pos + 1] + 1;
     
        // if the parent is at odd level, then
        // do a bitwise OR
        if ((level[pos] & 1) > 0)
            tree[pos] = tree[2 * pos + 1] |
                              tree[2 * pos + 2];
     
        // if the parent is at even level, then
        // do a bitwise XOR
        else
            tree[pos] = tree[2 * pos + 1] ^
                              tree[2 * pos + 2];
    }
     
    // function that updates the tree
    static void update(int low, int high, int pos,
                               int index, int []a)
    {
         
        // if it is a leaf and the leaf which is
        // to be updated
        if (low == high && low == index)
        {
            tree[pos] = a[low];
            return;
        }
     
        // out of range
        if (index < low || index > high)
            return;
     
        // not a leaf then recurse
        if (low != high)
        {
            int mid = (low + high) / 2;
     
            // recursive call
            update(low, mid, 2 * pos + 1, index, a);
             
            update(mid + 1, high, 2 * pos + 2,
                                          index, a);
     
            // check if the parent is at odd or
            // even level and perform OR or XOR
            // according to that
            if ((level[pos] & 1) > 0)
                tree[pos] = tree[2 * pos + 1] |
                                  tree[2 * pos + 2];
            else
                tree[pos] = tree[2 * pos + 1] ^
                                  tree[2 * pos + 2];
        }
    }
     
    // function that assigns value to a[index]
    // and calls update function to update the
    // tree
    static void updateValue(int index, int value,
                                   int []a, int n)
    {
        a[index] = value;
        update(0, n - 1, 0, index, a);
    }
     
    // Driver Code
    static public void main (String[] args)
    {
        int []a = { 1, 4, 5, 6 };
        int n = a.length;;
     
        // builds the tree
        constructTree(0, n - 1, 0, a);
     
        // 1st query
        int index = 0;
        int value = 2;
        updateValue(index, value, a, n);
        System.out.println(tree[0]);
     
        // 2nd query
        index = 3;
        value = 5;
        updateValue(index, value, a, n);
        System.out.println(tree[0]);
    }
}
 
// This code is contributed by vt_m.

Python3

# Python3 program to print the Leftover element
# after performing alternate Bitwise OR and
# Bitwise XOR operations to the pairs.
N = 1000
 
# array to store the tree
tree = [None] * N
 
# array to store the level of every parent
level = [None] * N
 
# function to construct the tree
def constructTree(low, high, pos, a):
  
    if low == high:
      
        # level of child is always 0
        level[pos], tree[pos] = 0, a[high]
        return
      
    mid = (low + high) // 2
 
    # Recursive call
    constructTree(low, mid, 2 * pos + 1, a)
    constructTree(mid + 1, high, 2 * pos + 2, a)
 
    # Increase the level of every parent,
    # which is level of child + 1
    level[pos] = level[2 * pos + 1] + 1
 
    # If the parent is at odd level,
    # then do a bitwise OR
    if level[pos] & 1:
        tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2]
 
    # If the parent is at even level,
    # then do a bitwise XOR
    else:
        tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2]
  
# Function that updates the tree
def update(low, high, pos, index, a):
  
    # If it is a leaf and the leaf
    # which is to be updated
    if low == high and low == index:
      
        tree[pos] = a[low]
        return
      
    # out of range
    if index < low or index > high:
        return
 
    # not a leaf then recurse
    if low != high:
      
        mid = (low + high) // 2
 
        # recursive call
        update(low, mid, 2 * pos + 1, index, a)
        update(mid + 1, high, 2 * pos + 2, index, a)
 
        # check if the parent is at odd or even level
        # and perform OR or XOR according to that
        if level[pos] & 1:
            tree[pos] = tree[2 * pos + 1] | tree[2 * pos + 2]
        else:
            tree[pos] = tree[2 * pos + 1] ^ tree[2 * pos + 2]
 
# Function that assigns value to a[index]
# and calls update function to update the tree
def updateValue(index, value, a, n):
  
    a[index] = value
    update(0, n - 1, 0, index, a)
  
# Driver Code
if __name__ == "__main__":
  
    a = [1, 4, 5, 6]
    n = len(a)
 
    # builds the tree
    constructTree(0, n - 1, 0, a)
 
    # 1st query
    index, value = 0, 2
    updateValue(index, value, a, n)
    print(tree[0])
 
    # 2nd query
    index, value = 3, 5
    updateValue(index, value, a, n)
    print(tree[0])
  
# This code is contributed by Rituraj Jain

C#

// C# program to print the Leftover
// element after performing alternate
// Bitwise OR and Bitwise XOR
// operations to the pairs.
using System;
 
public class GFG {
 
    static int N = 1000;
     
    // array to store the tree
    static int []tree = new int[N];
     
    // array to store the level of
    // every parent
    static int []level = new int[N];
     
    // function to construct the
    // tree
    static void constructTree(int low, int high,
                               int pos, int []a)
    {
        if (low == high)
        {
             
            // level of child is always 0
            level[pos] = 0;
            tree[pos] = a[high];
            return;
        }
        int mid = (low + high) / 2;
     
        // recursive call
        constructTree(low, mid, 2 * pos + 1, a);
         
        constructTree(mid + 1, high,
                                2 * pos + 2, a);
     
        // increase the level of every parent,
        // which is level of child + 1
        level[pos] = level[2 * pos + 1] + 1;
     
        // if the parent is at odd level,
        // then do a bitwise OR
        if ((level[pos] & 1) > 0)
            tree[pos] = tree[2 * pos + 1] |
                           tree[2 * pos + 2];
     
        // if the parent is at even level,
        // then do a bitwise XOR
        else
            tree[pos] = tree[2 * pos + 1] ^
                          tree[2 * pos + 2];
    }
     
    // function that updates the tree
    static void update(int low, int high,
               int pos, int index, int []a)
    {
         
        // if it is a leaf and the leaf
        // which is to be updated
        if (low == high && low == index)
        {
            tree[pos] = a[low];
            return;
        }
     
        // out of range
        if (index < low || index > high)
            return;
     
        // not a leaf then recurse
        if (low != high)
        {
            int mid = (low + high) / 2;
     
            // recursive call
            update(low, mid, 2 * pos + 1,
                                   index, a);
                                    
            update(mid + 1, high, 2 * pos + 2,
                                    index, a);
     
            // check if the parent is at odd
            // or even level and perform OR
            // or XOR according to that
            if ((level[pos] & 1) > 0)
                tree[pos] = tree[2 * pos + 1] |
                              tree[2 * pos + 2];
            else
                tree[pos] = tree[2 * pos + 1]
                            ^ tree[2 * pos + 2];
        }
    }
     
    // function that assigns value to a[index]
    // and calls update function to update
    // the tree
    static void updateValue(int index, int value,
                                 int []a, int n)
    {
        a[index] = value;
        update(0, n - 1, 0, index, a);
    }
     
    // Driver Code
    static public void Main ()
    {
        int []a = { 1, 4, 5, 6 };
        int n = a.Length;;
     
        // builds the tree
        constructTree(0, n - 1, 0, a);
     
        // 1st query
        int index = 0;
        int value = 2;
        updateValue(index, value, a, n);
        Console.WriteLine(tree[0]);
     
        // 2nd query
        index = 3;
        value = 5;
        updateValue(index, value, a, n);
        Console.WriteLine(tree[0]);
    }
}
 
// This code is contributed by vt_m.

输出:

1
3

时间复杂度

  • 树木结构:O(N)
  • 回答查询:O(log 2 N)

如果您希望与行业专家一起参加现场课程,请参阅《 Geeks现场课程》和《 Geeks现场课程美国》。