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

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++

  

#include <bits/stdc++.h>

using namespace std;

#define ll long long

  

ll mod = 1e9 + 7;

  

int countAndGood(int n, vector<int>& arr)

{

    

    int preAnd = (1 << 30) - 1;

  

    

    for (int i = 0; i < n; i++) {

        preAnd = (preAnd & arr[i]);

    }

  

    

    ll cnt = 0;

  

    

    

    for (int i = 0; i < n; i++) {

        if (preAnd == arr[i])

            cnt++;

    }

  

    

    ll ans = (cnt * (cnt - 1)) % mod;

  

    

    ll temp = 1;

    for (ll i = 2; i <= n - 2; i++) {

        temp = (temp * i) % mod;

    }

  

    

    ans = (ans * temp) % mod;

  

    

    return ans;

}

  

int main()

{

    int N = 4;

    vector<int> arr = { 1, 3, 5, 1 };

  

    

    cout << countAndGood(N, arr);

  

    return 0;

}

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

Related Articles:

 

Stay connected with us on social media platform for instant update click here to join our  Twitter, & Facebook We are now on Telegram. Click here to join our channel (@TechiUpdate) and stay updated with the latest Technology headlines. For all the latest Technology News Click Here 

Read original article here

Denial of responsibility! FineRadar is an automatic aggregator around the global media. All the content are available free on Internet. We have just arranged it in one platform for educational purpose only. In each content, the hyperlink to the primary source is specified. All trademarks belong to their rightful owners, all materials to their authors. If you are the owner of the content and do not want us to publish your materials on our website, please contact us by email – abuse@fineradar.com. The content will be deleted within 24 hours.
countfineradar updateFree Fire Redeem Codesgadget updateGeeksforGeeksindexLatest tech newspermutationsprefixSuffixTech Headlinestech newsTech News UpdatesTechnologyTechnology News
Comments (0)
Add Comment