热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

改变数组以使最大元素为数组的LCM的方法数

改变数组以使最大元素为数组的LCM的方法数原文:https:

改变数组以使最大元素为数组的 LCM 的方法数

原文:https://www . geeksforgeeks . org/更改数组的方式数-最大元素是数组的 LCM/

给定一个数组 arr[] ,任务是通过将给定数组的元素更新为[1,arr[i]]范围内的任何元素,使得更新后的数组的最小公倍数等于最大元素,来计算可以形成的唯一数组的数量。

示例:

输入: arr[] = {6,3}
输出: 13
解释:
可能的数组是–
{[1,1],[1,2],[2,2],[1,3],
[3,1],[3,3],[4,1],[4,2],[5,1],
[6,1],[6]

输入: arr[] = {1,4,3,2 }
T3】输出: 15

进场:


  • 为了使最大元素成为数组的 LCM,我们需要固定数组的最大元素。

  • 因为,我们已经固定了一些数字 i 作为最大值,现在 LCM 为 i ,我们需要确保数组中的每个元素都是 i 的倍数,包括 i

  • 我们将找到数字 i 的因子,并找到将它们放置在数组中的方法的数量。

  • 假设 i 的因子是 x, y, z 。因素的计数是 3

  • 假设 x  a 的位置数表示数组中有 a 个位置的个数大于等于 x ,让 y  b 个位置, z  c 个位置。

  • 现在 a 位置的 y  b - a 位置的 z  c - b - a 位置的 3 ^ a * 2 ^ {(b - a)} * 1 ^ {(c - b - a)} 等分配 x [/Tex]的方式有很多。

  • 现在,我们必须减去那些有 LCM  i 但没有 i 的路。

  • 我们需要从这些方式中减去 2 ^ b * 1 ^ {(c - b)}

  • 我们将使用位(二进制索引树)来查找大于某个数字 x 的位置数。

以下是上述方法的实现:

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 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         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         // 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 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             // 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             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 <    return 0;
}

Python 3

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

时间复杂度:  O(MAX * $\sqrt{MAX}$) ,其中 $MAX 是数组中最大的元素。


推荐阅读
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • 本文为Codeforces 1294A题目的解析,主要讨论了Collecting Coins整除+不整除问题。文章详细介绍了题目的背景和要求,并给出了解题思路和代码实现。同时提供了在线测评地址和相关参考链接。 ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • 本文讨论了一个数列求和问题,该数列按照一定规律生成。通过观察数列的规律,我们可以得出求解该问题的算法。具体算法为计算前n项i*f[i]的和,其中f[i]表示数列中有i个数字。根据参考的思路,我们可以将算法的时间复杂度控制在O(n),即计算到5e5即可满足1e9的要求。 ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
author-avatar
2364118915_86406b_479
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有