Open in App
Not now

# Number of ways to change the Array such that largest element is LCM of array

• Last Updated : 10 Sep, 2021

Given an array arr[], the task is to count the number of the unique arrays can be formed by updating the elements of the given array to any element in the range [1, arr[i]] such that the Least common multiple of the updated array is equal to the maximum element.

Examples:

Input: arr[] = {6, 3}
Output: 13
Explanation:
Possible Arrays are –
{[1, 1], [1, 2], [2, 1], [2, 2], [1, 3],
[3, 1], [3, 3], [4, 1], [4, 2], [5, 1],
[6, 1], [6, 2], [6, 3]}

Input: arr[] = {1, 4, 3, 2}
Output: 15

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Approach:

• For the maximum element to be the LCM of the array, we need to fix the maximum element of the array.
• As, we have fixed some number as maximum, now for the LCM to be , we’ll need to ensure that every element in the array is some multiple of including
• We’ll find the factors for the number and find the number of ways to place them in the array.
• Let’s say that the factors of be . The count of factors is .
• Let’s assume that number of positions that be means there are number of positions that have number in the array which is greater than equal to and let have positions and have positions.
• Now, number of ways to distribute x [/Tex] in positions, in positions and in positions are and so on.
• Now, we’ll have to subtract those ways which have LCM but is not there.
• We’ll need to subtract from the ways.
• We’ll use BIT(Binary Indexed Tree) to find number of positions greater than some number .

Below is the implementation of the above approach:

## C++

 // C++ implementation to find the  // Number of ways to change the array  // such that maximum element of the  // array is the LCM of the array     #include  using namespace std;     // Modulo  const int MOD = 1e9 + 7;  const int N = 1e5 + 5;     // Fenwick tree to find number  // of indexes greater than x  vector<int> BIT(N, 0);     // Function to compute  // x ^ y % MOD  int power(int x, int y)  {      if (x == 0)          return 0;         int ans = 1;         // Loop to compute the      // x^y % MOD      while (y > 0) {          if (y & 1)              ans = (1LL * ans * x) % MOD;             x = (1LL * x * x) % MOD;          y >>= 1;      }      return ans;  }     // Function to update the binary  // indexed tree  void updateBIT(int idx, int val)  {      assert(idx > 0);      while (idx < N) {          BIT[idx] += val;          idx += idx & -idx;      }  }     // Function to find the prefix sum  // upto the current index  int queryBIT(int idx)  {      int ans = 0;      while (idx > 0) {          ans += BIT[idx];          idx -= idx & -idx;      }      return ans;  }     // Function to find the number of  // ways to change the array such  // that the LCM of array is  // maximum element of the array  int numWays(int arr[], int n)  {         int mx = 0;      for (int i = 0; i < n; i++) {             // Updating BIT with the          // frequency of elements          updateBIT(arr[i], 1);             // Maximum element in the array          mx = max(mx, arr[i]);      }         // 1 is for every element      // is 1 in the array;      int ans = 1;      for (int i = 2; i <= mx; i++) {             // Vector for storing the factors          vector<int> factors;          for (int j = 1; j * j <= i; j++) {                 // finding factors of i              if (i % j == 0) {                  factors.push_back(j);                  if (i / j != j)                      factors.push_back(i / j);              }          }          // Sorting in descending order          sort(factors.rbegin(), factors.rend());             int cnt = 1;             // for storing number of indexex          // greater than the i - 1 element          int prev = 0;          for (int j = 0; j < factors.size(); j++) {                 // Number of remaining factors              int remFactors = int(factors.size()) - j;                 // Number of indexes in the array              // with element factor[j] and above              int indexes = n - queryBIT(factors[j] - 1);                 // Multiplying count with              // remFcators ^ (indexes - prev)              cnt = (1LL                     * cnt                     * power(remFactors,                             indexes - prev))                    % MOD;              prev = max(prev, indexes);          }             // Remove those counts which have          // lcm as i but i is not present          factors.erase(factors.begin());             int toSubtract = 1;          prev = 0;             // Loop to find the count which have          // lcm as i  but i is not present          for (int j = 0; j < factors.size(); j++) {              int remFactors = int(factors.size()) - j;              int indexes = n - queryBIT(factors[j] - 1);                 toSubtract = (1LL                            * toSubtract                            * power(remFactors,                                    indexes - prev));              prev = max(prev, indexes);          }             // Adding cnt - toSubtract to answer          ans = (1LL * ans + cnt                 - toSubtract + MOD)                % MOD;      }      return ans;  }     // Driver Code  int main()  {      int arr[] = { 6, 3 };      int n = sizeof(arr) / sizeof(arr[0]);         int ans = numWays(arr, n);      cout << ans << endl;      return 0;  }

## Python3

 # Python implementation to find the   # Number of ways to change the array  # such that maximum element of the  # array is the LCM of the array     # Modulo  MOD = int(1e9) + 9 MAXN = int(1e5) + 5    # Fenwick tree to find number  # of indexes greater than x  BIT = [0 for _ in range(MAXN)]     # Function to compute  # x ^ y % MOD  def power(x, y):      if x == 0:          return 0     ans = 1            # Loop to compute the       # x ^ y % MOD      while y > 0:          if y % 2 == 1:              ans = (ans * x) % MOD          x = (x * x) % MOD          y = y // 2     return ans     # Function to update the   # Binary Indexed Tree  def updateBIT(idx, val):             # Loop to update the BIT      while idx < MAXN:          BIT[idx] += val          idx += idx & (-idx)     # Function to find   # prefix sum upto idx  def queryBIT(idx):      ans = 0     while idx > 0:          ans += BIT[idx]          idx -= idx & (-idx)      return ans     # Function to find number of ways  # to change the array such that  # MAX of array is same as LCM  def numWays(arr):      mx = 0            # Updating BIT with the      # frequency of elements      for i in arr:          updateBIT(i, 1)                     # Maximum element           # in the array          mx = max(mx, i)         ans = 1     for i in range(2, mx + 1):                     # For storing factors of i          factors = []          for j in range(1, i + 1):              if j * j > i:                  break                                # Finding factors of i              if i % j == 0:                  factors.append(j)                  if i // j != j:                      factors.append(i // j)             # Sorting in descending order          factors.sort()          factors.reverse()                     # For storing ans          cnt = 1                    # For storing number of indexes          # greater than the i - 1 element          prev = 0         for j in range(len(factors)):                             # Number of remaining factors              remFactors = len(factors) - j                             # Number of indexes in the array              # with element factor[j] and above              indexes = len(arr) - queryBIT(factors[j] - 1)                             # Multiplying count with               # remFcators ^ (indexes - prev)              cnt = (cnt * power(remFactors, \                       indexes - prev)) % MOD              prev = max(prev, indexes)             # Remove those counts which have          # lcm as i but i is not present          factors.remove(factors[0])             toSubtract = 1         prev = 0         for j in range(len(factors)):              remFactors = len(factors) - j              indexes = len(arr) - queryBIT(factors[j] - 1)                 toSubtract = (toSubtract *\                power(remFactors, indexes - prev))              prev = max(prev, indexes)             # Adding cnt - toSubtract to ans;          ans = (ans + cnt - toSubtract + MOD) % MOD;                 return ans     # Driver Code  if __name__ == "__main__":      arr = [1, 4, 3, 2]             ans = numWays(arr);      print(ans)

Output:

13


Time Complexity: , where is the maximum element in the array.

My Personal Notes arrow_drop_up
Related Articles