📜  求幂K的所有对的绝对差之和

📅  最后修改于: 2021-05-18 00:20:58             🧑  作者: Mango

给定N个整数的数组arr []和一个数K ,任务是找到给定数组中所有对数乘幂K的对的绝对差之和,即 \sum_{i=1}^{N} \sum_{j=1}^{N} \ |arr[i]-arr[j]|^K

例子:

幼稚的方法:想法是生成所有可能的对,并找出提高到幂K的每一对的绝对差,并将它们加在一起。

时间复杂度: O((log K)* N 2 )
辅助空间: O(1)

高效的方法:我们可以通过以下计算来提高朴素方法的时间复杂度:
对于所有可能的对,我们必须找到的值

由于对于对(arr [i],arr [j])的值|arr[i]-arr[j]|^{K}被两次计算。所以上面的等式也可以写成:

写作|arr[i]-arr[j]|^{K}根据二项式:

令Pre [i] [a] =  \sum_{j=1}^{i-1}(-arr[j])^{K - a} (式2)

根据公式1和公式2,我们得到

Pre [i] [a]的值可以计算为:

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
#define ll long long
using namespace std;
  
class Solution {
  
public:
    // Since K can be 100 max
    ll ncr[101][101];
    int n, k;
    vector A;
  
    // Constructor
    Solution(int N, int K, vector B)
    {
        // Initializing with -1
        memset(ncr, -1, sizeof(ncr));
  
        n = N;
        k = K;
        A = B;
  
        // Making vector A as 1-Indexing
        A.insert(A.begin(), 0);
    }
  
    ll f(int N, int K);
  
    ll pairsPower();
};
  
// To Calulate the value nCk
ll Solution::f(int n, int k)
{
    if (k == 0)
        return 1LL;
  
    if (n == k)
        return 1LL;
  
    if (n < k)
        return 0;
  
    if (ncr[n][k] != -1)
        return ncr[n][k];
  
    // Since nCj = (n-1)Cj + (n-1)C(j-1);
    return ncr[n][k] = f(n - 1, k)
                       + f(n - 1, k - 1);
}
  
// Function that summation of absolute
// differences of all pairs raised
// to the power k
ll Solution::pairsPower()
{
    ll pre[n + 1][k + 1];
    ll ans = 0;
  
    // Sort the given array
    sort(A.begin() + 1, A.end());
  
    // Precomputation part, O(n*k)
    for (int i = 1; i <= n; ++i) {
        pre[i][0] = 1LL;
  
        for (int j = 1; j <= k; j++) {
            pre[i][j] = A[i]
                        * pre[i][j - 1];
        }
  
        if (i != 1) {
            for (int j = 0; j <= k; ++j)
                pre[i][j] = pre[i][j]
                            + pre[i - 1][j];
        }
    }
  
    // Traverse the array arr[]
    for (int i = n; i >= 2; --i) {
  
        // For each K
        for (int j = 0; j <= k; j++) {
  
            ll val = f(k, j);
  
            ll val1 = pow(A[i], k - j)
                      * pre[i - 1][j];
  
            val = val * val1;
  
            if (j % 2 == 0)
                ans = (ans + val);
  
            else
                ans = (ans - val);
        }
    }
  
    ans = 2LL * ans;
  
    // Return the final answer
    return ans;
}
  
// Driver Code
int main()
{
    // Given N and K
    int N = 3;
    int K = 3;
  
    // Given array
    vector arr = { 1, 2, 3 };
  
    // Creation of Object of class
    Solution obj(N, K, arr);
  
    // Function Call
    cout << obj.pairsPower() << endl;
    return 0;
}


Python3
# Python3 program for the above approach
class Solution:
      
    def __init__(self, N, K, B):
  
        self.ncr = []
          
        # Since K can be 100 max
        for i in range(101):
            temp = []
            for j in range(101):
                  
                # Initializing with -1
                temp.append(-1)
                  
            self.ncr.append(temp)
  
        self.n = N
        self.k = K
  
        # Making vector A as 1-Indexing
        self.A = [0] + B
  
    # To Calulate the value nCk
    def f(self, n, k):
          
        if k == 0:
            return 1
        if n == k:
            return 1
        if n < k:
            return 0
              
        if self.ncr[n][k] != -1:
            return self.ncr[n][k]
  
        # Since nCj = (n-1)Cj + (n-1)C(j-1);
        self.ncr[n][k] = (self.f(n - 1, k) + 
                          self.f(n - 1, k - 1))
                            
        return self.ncr[n][k]
  
    # Function that summation of absolute
    # differences of all pairs raised
    # to the power k
    def pairsPower(self):
          
        pre = []
          
        for i in range(self.n + 1):
            temp = []
            for j in range(self.k + 1):
                temp.append(0)
                  
            pre.append(temp)
  
        ans = 0
  
        # Sort the given array
        self.A.sort()
  
        # Precomputation part, O(n*k)
        for i in range(1, self.n + 1):
            pre[i][0] = 1
  
            for j in range(1, self.k + 1):
                pre[i][j] = (self.A[i] * 
                                pre[i][j - 1])
  
            if i != 1:
                for j in range(self.k + 1):
                    pre[i][j] = (pre[i][j] + 
                                 pre[i - 1][j])
  
        # Traverse the array arr[]
        for i in range(self.n, 1, -1):
              
            # For each K
            for j in range(self.k + 1):
                val = self.f(self.k, j)
                val1 = (pow(self.A[i], 
                            self.k - j) *
                             pre[i - 1][j])
  
                val = val * val1
  
                if j % 2 == 0:
                    ans = ans + val
                else:
                    ans = ans - val
  
        ans = 2 * ans
  
        # Return the final answer
        return ans
  
# Driver code
if __name__ == '__main__':
  
    # Given N and K
    N = 3
    K = 3
      
    # Given array
    arr = [ 1, 2, 3 ]
  
    # Creation of object of class
    obj = Solution(N, K, arr)
      
    # Function call
    print(obj.pairsPower())
  
# This code is contributed by Shivam Singh


输出:
20

时间复杂度: O(N * K)
辅助空间: O(N * K)