【问题标题】:A problem of taking combination for set theory集合论的一个组合问题
【发布时间】:2019-07-29 12:05:24
【问题描述】:

给定一个大小为 N 的数组 A。数组 A 的子集的值定义为该子集中所有数字的乘积。我们必须返回数组 A %(10^9+7) 的所有可能非空子集的值的乘积。

例如数组 A {3,5}

` 值{3} = 3, 值{5} = 5, 值{3,5} = 5*3 = 15

答案 = 3*5*15 %(10^9+7)。

谁能解释一下这个问题背后的数学原理。我正在考虑通过组合来解决它以有效地解决它。

我尝试过使用蛮力,它给出了正确的答案,但它太慢了。 下一个方法是使用组合。现在我认为,如果我们取所有集合并将这些集合中的所有数字相乘,那么我们将得到正确的答案。因此,我必须找出一个数字在计算答案时出现了多少次。在示例中,5 和 3 都出现了 2 次。如果我们仔细观察,a 中的每个数字都会出现相同的次数。

【问题讨论】:

  • 如果您需要数学方面的帮助,请转至the Math SE site。一旦您了解了问题背后的数学原理并且在尝试实现它时遇到了问题,那么非常欢迎您回到这里寻求代码方面的帮助。
  • 我不太明白。您能否在hackerearth或codechef或某处添加原始问题的链接。谢谢
  • 它正在测试中,现在链接无效。

标签: c++ algorithm math combinations


【解决方案1】:

你正朝着正确的方向前进。

x 成为给定数组A 的一个元素。在我们的最终答案中,x 出现p 的次数,其中p 等于A 可能包含x 的子集的数量。

如何计算p?一旦我们决定将x 包含在我们的子集中,我们对于其余的N-1 元素有两种选择:将它们包含在集合中或不包含在集合中。所以,我们得出结论p = 2^(N-1)

因此,A 的每个元素在最终产品中恰好出现2^(N-1) 次。剩下的就是计算答案:(a1 * a2 * ... * an)^p。由于指数很大,可以使用binary exponentiation进行快速计算。

正如 Matt Timmermans 在下面的 cmets 中建议的那样,我们无需实际计算 p = 2^(N-1) 即可获得我们的答案。我们首先计算乘积a1 * a2 * ... * an。然后,我们简单地将这个产品平方n-1 次。

C++中对应的代码:

int func(vector<int> &a) {
    int n = a.size();
    int m = 1e9+7;
    if(n==0) return 0;
    if(n==1) return (m + a[0]%m)%m;

    long long ans = 1;

    //first calculate ans = (a1*a2*...*an)%m
    for(int x:a){
        //negative sign does not matter since we're squaring
        if(x<0) x *= -1;
        x %= m;
        ans *= x;
        ans %= m;
    }

    //now calculate ans = [ ans^(2^(n-1)) ]%m
    //we do this by squaring ans n-1 times
    for(int i=1; i<n; i++){
        ans = ans*ans;
        ans %= m;
    }

    return (int)ans;
}

【讨论】:

  • 请注意,指数太大而无法放入普通整数类型,但它的位有一个非常简单的模式,因此您可以在不实际创建指数的情况下进行指数运算。
【解决方案2】:

让, A={a,b,c}
A 的所有可能子集是 ={{},{a},{b},{c},{a,b},{b,c},{c,a},{a,b,c,d} }
这里每个元素的出现次数是 4 次。
因此,如果 A={a,b,c,d},则每个元素的出现次数将为 2^3。
因此,如果 A 的大小为 n,则每个元素的出现次数将为 2^(n-1)

所以最终结果将是 = a1^p*a2^pa3^p....*an^p
其中 p 是 2^(n-1)

我们需要解 x^2^(n-1) % mod。

我们可以将 x^2^(n-1) % mod 写成 x^(2^(n-1) % phi(mod)) %mod 。 link
因为 mod 是素数,所以 phi(mod)=mod-1。

所以首先找到 p= 2^(n-1) %(mod-1)。
然后为每个数字找到 Ai^p % mod 并乘以最终结果。

【讨论】:

  • 我在取了一些数字后得到了相同的答案。我正在寻找的是推导或解释,以便我可以解决类似的问题。
【解决方案3】:

我阅读了之前的答案,并且了解了制作套装的过程。所以在这里我试图把它尽可能简单地放在人们身上,以便他们可以将它应用于类似的问题。

让 i 成为数组 A 的一个元素。按照问题中给出的方法,i 在最终答案中出现 p 次。

现在,我们如何制作不同的套装。我们取只包含一个元素的集合,然后是包含两个组的集合,然后是 3 个组……n 个元素组。 现在我们想知道,每当我们制作一组特定数字时,比如 3 个元素的组,这些集合中有多少包含 i? 有 n 个元素,因此对于始终包含 i 的 3 个元素的集合,组合是 (n-1)C(3-1),因为我们可以从 n-1 个元素中选择 3-1 个元素。 如果我们对每个组都这样做,p = [ (n-1)C(x-1) ] ,m 从 1 到 n。因此,p= 2^(n-1)。

同样地,对于每个元素 i,p 都是相同的。因此我们得到 最终答案= A[0]^p *A[1]^p...... A[n]^p

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多