📌  相关文章
📜  所有子序列的宽度总和(最大和最小差异)

📅  最后修改于: 2021-04-28 18:08:02             🧑  作者: Mango

给定整数数组A [] 。任务是返回A的所有子序列的宽度之和。对于任何序列SS的宽度是S的最大元素和最小元素之间的差。

注意:由于答案可能很大,所以以10 ^ 9 + 7为模输出答案。

例子:

这个想法是首先数组进行排序,因为对数组进行排序不会影响最终答案。排序后,这使我们知道最小A [i]最大A [j]的子序列数将是2 ji-1

因此,我们的答案可以归结为:

\sum_{j>i}(2^{j-i-1})(A_{j}-A_{i})= (\sum_{i=0}^{n-2}\sum_{j=i+1}^{n-1}(2^{j-i-1})(A_{j}))-(\sum_{i=0}^{n-2}\sum_{j=i+1}^{n-1}(2^{j-i-1})(A_{i})) = ((2^{0}A_{1}+2^{1}A_{2}+2^{2}A_{3}+...)+(2^{0}A_{2}+2^{1}A_{3}+2^{2}A_{4}+...)+(2^{0}A_{3}+2^{1}A_{4}+2^{2}A_{5}+...)+...)-      (\sum_{i=0}^{n-2}(2^{0}+2^{1}+...+2^{N-i-2})A_{i}+...)= (\sum_{j=1}^{n-1}(2^{j}-1)A_{j})-(\sum_{i=0}^{n-2}(2^{N-i-1}-1)A_{i})= \sum_{i=0}^{n-1}((2^{i}-1)A_{i}-(2^{N-i-1}-1)A_{i})= \sum_{i=0}^{n-1}(2^{i}-2^{N-i-1})A_{i}

下面是上述方法的实现:

C++
// CPP implementation of above approach
#include 
using namespace std;
  
#define MOD 1000000007
  
// Function to return sum of width of all subsets
int SubseqWidths(int A[], int n)
{
    // Sort the array
    sort(A, A + n);
  
    int pow2[n];
    pow2[0] = 1;
  
    for (int i = 1; i < n; ++i)
        pow2[i] = (pow2[i - 1] * 2) % MOD;
  
    int ans = 0;
  
    for (int i = 0; i < n; ++i)
        ans = (ans + (pow2[i] - pow2[n - 1 - i]) * A[i]) % MOD;
  
    return ans;
}
  
// Driver program
int main()
{
    int A[] = { 5, 6, 4, 3, 8 };
  
    int n = sizeof(A) / sizeof(A[0]);
  
    cout << SubseqWidths(A, n);
  
    return 0;
}


Java
// Java implementation of above approach
import java.util.Arrays; 
  
class GFG{
static int MOD=1000000007;
  
// Function to return sum of width of all subsets
static int SubseqWidths(int[] A, int n)
{
    // Sort the array
    Arrays.sort(A);
  
    int[] pow2=new int[n];
    pow2[0] = 1;
  
    for (int i = 1; i < n; ++i)
        pow2[i] = (pow2[i - 1] * 2) % MOD;
  
    int ans = 0;
  
    for (int i = 0; i < n; ++i)
        ans = (ans + (pow2[i] - 
                pow2[n - 1 - i]) * A[i]) % MOD;
  
    return ans;
}
  
// Driver program
public static void main(String[] args)
{
    int[] A = new int[]{ 5, 6, 4, 3, 8 };
  
    int n = A.length;
  
    System.out.println(SubseqWidths(A, n));
}
}
// This code is contributed by mits


Python
# Python3 implementation of above approach
  
# Function to return sum of width of all subsets
def SubseqWidths(A):
    MOD = 10**9 + 7
    N = len(A)
    A.sort()
  
    pow2 = [1]
    for i in range(1, N):
        pow2.append(pow2[-1] * 2 % MOD)
  
    ans = 0
    for i, x in enumerate(A):
        ans = (ans + (pow2[i] - pow2[N - 1 - i]) * x) % MOD
    return ans
  
  
# Driver program
A = [5, 6, 4, 3, 8]
  
print(SubseqWidths(A))


C#
// C# implementation of above approach
using System;
  
class GFG
{
static int MOD = 1000000007;
  
// Function to return sum of 
// width of all subsets
static int SubseqWidths(int[] A, int n)
{
    // Sort the array
    Array.Sort(A);
  
    int[] pow2 = new int[n];
    pow2[0] = 1;
  
    for (int i = 1; i < n; ++i)
        pow2[i] = (pow2[i - 1] * 2) % MOD;
  
    int ans = 0;
  
    for (int i = 0; i < n; ++i)
        ans = (ans + (pow2[i] - 
                       pow2[n - 1 - i]) * 
                       A[i]) % MOD;
  
    return ans;
}
  
// Driver Code
static void Main()
{
    int[] A = new int[]{ 5, 6, 4, 3, 8 };
  
    int n = A.Length;
      
    Console.WriteLine(SubseqWidths(A, n));
}
}
  
// This code is contributed by mits


PHP


输出:
87

时间复杂度: O(N * log(N)),其中N是A的长度。