11.小和问题(归并排序拓展)

小和问题:
在一个数组中,每一个数左边比当前数小的数累加起来,叫做这个数
的小和。求一个数组 的小和。
例子:[1,3,4,2,5] 1左边比1小的数,没有; 3左边比3小的数,1; 4左
边比4小的数,1、3; 2左边比2小的数,1; 5左边比5小的数,1、3、4、
2; 所以小和为1+1+3+1+1+3+4+2=16

int Merge(int arr[], int left, int mid, int right)
{
  if (right == left) return 0;
    
  int *pTemp = new int[right-left+1];
  int i = 0;
  int res = 0;
  int p = mid + 1;
  while (left <= mid && p <= right)
  {
    res += arr[left] < arr[p] ? arr[left]*arr[right-p+1] : 0;
    pTemp[i++] = arr[left] <= arr[p] ? arr[p++] : arr[left++]; 
  }
    
  while (left <= mid)
  {
    pTemp[i++] = arr[left++];
  }
    
  while (p <= right)
  {
    pTemp[i++] = arr[p++];
  }
    
  for (int j = 0; j <= right-left+1; j++)
  {
    arr[left+j] = pTemp[j];
  }
    
   return res;
    
}

int SmallSum(int arr[], int left, int right)
{
  if (!arr) return 0;
  if (left == right) return 0;
    
  int mid = left + ((right-left)>>1);
   
  return SmallSum(arr, left, mid) + SmallSum(arr, mid+1, right) + Merge(arr, left, mid, right);

}
posted @ 2022-09-09 16:12  test369  阅读(49)  评论(0编辑  收藏  举报