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

📅  最后修改于: 2021-04-17 09:20:04             🧑  作者: 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


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)