Count permutations whose prefix & suffix AND are same for each index
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: 6
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) |
4
Time Complexity: O(N)
Auxiliary Space: O(1)
Related Articles:
Please Login to comment...