Open In App

Count permutations whose prefix & suffix AND are same for each index

Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[] of size N, Return the number of permutations of array arr[] which satisfy the condition arr[1] & arr[2] & . . . & arr[i] = arr[i+1] & arr[i+2] & . . . & arr[N] , for all i.

Note: Here & denotes the bitwise AND operation.

Examples:

Input: N = 3, arr[] = { 1, 1, 1 } 
Output:
Explanation: Since all the numbers are equal, whatever permutation we take, the sequence will follow the above condition. There are a total of 6 permutations possible with index numbers from 1 to 3 : [1,  2,  3],  [1,  3,  2],  [2, 1, 3],  [2, 3, 1],  [3, 1,  2],  [3, 2, 1].

Input: N = 4, arr[] = { 1, 3, 5, 1 }
Output: 4

Approach: This problem can be solved based on the following idea:

Consider an arbitrary sequence b1, b2, . . ., bn. First, let us define the arrays AND_pref and AND_suf of length N where 

  • AND_prefi = b1 & b2 & . . . & bi and 
  • AND_sufi = bi & bi+1 & . . . & bn.

According to the definition of the sequence: AND_pref1 = AND_suf2. Now AND_pref2 ? AND_pref1 = AND_suf2 ? AND_suf3. Also according to the definition, AND_pref2 = AND_suf3. This means that b1 = AND_pref2 = AND_suf3. 

Similarly, for all i from 1 to n, we get AND_prefi = b1 and AND_sufi = b1.
Therefore for the sequence, b1 = bn and the bi must be a super mask of  b1 for all i from 2 to n ? 1.

Follow the steps below to solve the problem:

  • Initialize a variable preAnd with ( 1 << 30 ) – 1.
  • Run a loop from i = 0 to n-1 and update preAnd with ( preAnd & arr[i] ).   
  • Initialize a count variable (say cnt) with 0.
  • Run a loop from i = 0 to n – 1 
    • If preAnd = arr[i], then Increment cnt by 1.
    • Compute (cnt * ( cnt – 1 ) * (n – 2) !) % (1e9 + 7) and store it in the answer variable.
  • Return the answer.

Below is the implementation of the above approach:

C++




// C++ code to implement the above approach
 
#include <bits/stdc++.h>
using namespace std;
#define ll long long
 
// Given mod number .
ll mod = 1e9 + 7;
 
// Function performing calculation
int countAndGood(int n, vector<int>& arr)
{
    // Initializing preAnd .
    int preAnd = (1 << 30) - 1;
 
    // Precomputing the And of the array arr
    for (int i = 0; i < n; i++) {
        preAnd = (preAnd & arr[i]);
    }
 
    // Initializing cnt with 0
    ll cnt = 0;
 
    // Counting the total number in arr which
    // are equal to preAnd
    for (int i = 0; i < n; i++) {
        if (preAnd == arr[i])
            cnt++;
    }
 
    // Finding (cnt)P(cnt-2)
    ll ans = (cnt * (cnt - 1)) % mod;
 
    // Finding (n-2)!
    ll temp = 1;
    for (ll i = 2; i <= n - 2; i++) {
        temp = (temp * i) % mod;
    }
 
    // Multiplying temp and ans
    ans = (ans * temp) % mod;
 
    // Returning ans variable
    return ans;
}
 
// Driver code
int main()
{
    int N = 4;
    vector<int> arr = { 1, 3, 5, 1 };
 
    // Function call
    cout << countAndGood(N, arr);
 
    return 0;
}


Java




// Java code to implement the above approach
import java.util.*;
 
class GFG {
    // Given mod number .
    static final int mod = (int)(1e9 + 7);
 
    // Function performing calculation
    static int countAndGood(int n, List<Integer> arr)
    {
 
        // Initializing preAnd .
        int preAnd = (1 << 30) - 1;
 
        // Precomputing the And of the array arr
        for (int i = 0; i < n; i++) {
            preAnd = (preAnd & arr.get(i));
        }
 
        // Initializing cnt with 0
        long cnt = 0;
 
        // Counting the total number in arr which
        // are equal to preAnd
        for (int i = 0; i < n; i++) {
            if (preAnd == arr.get(i))
                cnt++;
        }
 
        // Finding (cnt)P(cnt-2)
        long ans = (cnt * (cnt - 1)) % mod;
 
        // Finding (n-2)!
        long temp = 1;
        for (long i = 2; i <= n - 2; i++) {
            temp = (temp * i) % mod;
        }
 
        // Multiplying temp and ans
        ans = (ans * temp) % mod;
 
        // Returning ans variable
        return (int)ans;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int N = 4;
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(3);
        arr.add(5);
        arr.add(1);
 
        // Function Call
        System.out.println(countAndGood(N, arr));
    }
}
// This Code is Contributed by Prasad Kandekar(prasad264)


Python3




# Python code to implement the above approach
 
# Given mod number .
MOD = int(1e9 + 7)
 
# Function performing calculation
 
 
def countAndGood(n, arr):
 
    # Initializing preAnd .
    preAnd = (1 << 30) - 1
 
    # Precomputing the And of the array arr
    for i in range(n):
        preAnd &= arr[i]
 
        # Initializing cnt with 0
    cnt = 0
 
    # Counting the total number in arr which
    # are equal to preAnd
    for i in range(n):
        if preAnd == arr[i]:
            cnt += 1
 
    # Finding (cnt)P(cnt-2)
    ans = (cnt * (cnt - 1)) % MOD
 
    # Finding (n-2)!
    temp = 1
    for i in range(2, n - 2 + 1):
        temp = (temp * i) % MOD
 
    # Multiplying temp and ans
    ans = (ans * temp) % MOD
 
    # Returning ans variable
    return ans
 
 
# Driver Code
N = 4
arr = [1, 3, 5, 1]
 
# Function Call
print(countAndGood(N, arr))
# This Code is Contributed by Prasad Kandekar(prasad264)


C#




// C# code to implement the above approach
 
using System;
using System.Collections;
 
class Gfg
{
  // Given mod number .
  static long mod = 1000000007;
 
  // Function performing calculation
  static long countAndGood(int n, int[] arr)
  {
    // Initializing preAnd .
    int preAnd = (1 << 30) - 1;
 
    // Precomputing the And of the array arr
    for (int i = 0; i < n; i++) {
      preAnd = (preAnd & arr[i]);
    }
 
    // Initializing cnt with 0
    long cnt = 0;
 
    // Counting the total number in arr which
    // are equal to preAnd
    for (int i = 0; i < n; i++) {
      if (preAnd == arr[i])
        cnt++;
    }
 
    // Finding (cnt)P(cnt-2)
    long ans = (cnt * (cnt - 1)) % mod;
 
    // Finding (n-2)!
    long temp = 1;
    for (long i = 2; i <= n - 2; i++) {
      temp = (temp * i) % mod;
    }
 
    // Multiplying temp and ans
    ans = (ans * temp) % mod;
 
    // Returning ans variable
    return ans;
  }
 
  // Driver code
  static void Main(string[] args)
  {
    int N = 4;
    int[] arr = { 1, 3, 5, 1 };
 
    // Function call
    Console.Write(countAndGood(N, arr));
 
  }
}
 
// this code is contributed by poojaagarwal2.


Javascript




// Javascript code to implement the above approach
 
// Given mod number .
const MOD = 1e9 + 7;
 
// Function performing calculation
function countAndGood(n, arr) {
 
    // Initializing preAnd .
    var preAnd = (1 << 30) - 1;
 
    // Precomputing the And of the array arr
    for (var i = 0; i < n; i++) {
        preAnd &= arr[i];
    }
 
    // Initializing cnt with 0
    var cnt = 0;
     
    // Counting the total number in arr which
    // are equal to preAnd
    for (var i = 0; i < n; i++) {
        if (preAnd === arr[i]) {
            cnt++;
        }
    }
 
    // Finding (cnt)P(cnt-2)
    var ans = (cnt * (cnt - 1)) % MOD;
     
    // Finding (n-2)!
    var temp = 1;
    for (var i = 2; i <= n - 2; i++) {
        temp = (temp * i) % MOD;
    }
 
    // Multiplying temp and ans
    ans = (ans * temp) % MOD;
 
    // Returning ans variable
    return ans;
}
 
// Driver Code
var N = 4;
var arr = [1, 3, 5, 1];
 
// Function Call
console.log(countAndGood(N, arr));
// This Code is Contributed by Prasad Kandekar(prasad264)


Output

4

Time Complexity: O(N) 
Auxiliary Space: O(1)

Related Articles:



Last Updated : 07 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads