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);
}