# Leftover element after performing alternate Bitwise OR and Bitwise XOR operations on adjacent pairs

• Difficulty Level : Hard
• Last Updated : 11 Nov, 2021

Given an array of N(always a power of 2) elements and Q queries.
Every query consists of two elements, an index, and a value… We need to write a program that assigns value to Aindex and prints the single element which is left after performing the below operations for each query:

• At alternate steps, perform bitwise OR and bitwise XOR operations on the adjacent elements.
• In the first iteration, select, select n/2 pairs moving from left to right, and do a bitwise OR of all the pair values. In the second iteration, select (n/2)/2 leftover pairs and do a bitwise XOR on them. In the third iteration, select, select ((n/2)/2)/2 leftover pairs moving from left to right, and do a bitwise OR of all the pair values.
• Continue the above steps till we are left with a single element.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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

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

Naive Approach: The naive approach is to perform every step till we are leftover with one element. Using a 2-D vector, we will store the resultant elements left after every step. V[steps-1][0..size] gives the number of elements at the previous step. If the step number is odd, we perform a bitwise OR operation, else a bitwise XOR operation is done. Repeat the steps till we have a leftover with one element. The last element left will be our answer.

Below is the implementation of the naive approach:

## 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 Codeint 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 Codepublic 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 Codepublic 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



Output:

1
3

Time Complexity: O(N * 2N
Space Complexity: O(N ^ 2)

Efficient Approach: The efficient approach is to use a Segment tree. Below is the complete segment tree approach used to solve the problem.

Building the tree
The leaves of the segment tree will store the array of values and their parents will store the OR of the leaves. Moving upward in the tree, with every alternate step, the parent stores either bitwise XOR or bitwise OR between the left and right child. At every odd-numbered iteration, we perform the bitwise OR of the pairs, and similarly, we perform the bitwise XOR of pairs at every even-numbered operation. So the odd-numbered parent will store the bitwise OR of the left and right child. Similarly, the even-numbered parent stores the bitwise XOR of the left and right child. level[] is an array that stores levels of every parent starting from 1, to determine if the pair(right child and left child) below it performs an OR operation or an XOR operation. The root of the tree will be our answer to the given sequence after every update operation.

.The image above explains the construction of the tree. If the sequence was [1, 2, 3, 4, 5, 6, 7, 8], then after 3 iterations, we will be left over with 12 which is our answer and is stored at the root.

There is no need to rebuild the complete tree to perform an update operation. To do an update, we should find a path from the root to the corresponding leaf and recalculate the values only for the parents that are lying on the found path.
Level of parent:
Using DP on trees, we can easily store the level of every parent. Initialize the leaf nodes level to 0, and keep adding as we move up to every parent.
The recurrence relation for calculating the level of parent is:

level[parent] = level[child] + 1
Here, a child is 2*pos + 1 or 2*pos + 2

Below is the implementation of the above approach:

## 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 treeint tree[N];  // array to store the level of every parentint level[N];  // function to construct the treevoid 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 treevoid 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 treevoid updateValue(int index, int value, int a[], int n){    a[index] = value;    update(0, n - 1, 0, index, a);}  // Driver Codeint 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.

## Javascript



Output:

1
3

Time Complexity:

• Tree construction: O(N)