小和问题
作者:
hongye
,
2025-03-12 19:59:23
·辽宁
,
所有人可见
,
阅读 1
//小和问题,归并排序解决的问题的一种,将问题归纳为左半的值,加右边的值,加跨越左边和右边的值,以及这个问题能否排序解决
//https://www.nowcoder.com/practice/edfe05a1d45c4ea89101d936cac32469
#include <iostream>
#include <stdio.h>
using namespace std;
typedef long long LL;
const int N = 100010;
int arr[N] , help[N] , n;
LL marge(int left , int right , int mid){
LL ans = 0;
int temp = 0;
int l = left , r = mid+1 , k = left;
for(int i=left,j=mid+1;j<=right;j++){
while(i <= mid && arr[i] <= arr[j]) temp+=arr[i++];
ans += temp;
}
//cout<<left<<" "<<mid<<" "<<right<<endl;
while(l <= mid && r <= right){
if(arr[l] <= arr[r]){
help[k++] = arr[l++];
}else{
help[k++] = arr[r++];
}
}
while(l<=mid) help[k++] = arr[l++];
while(r<=right) help[k++] = arr[r++];
for(l=left;l<=right;l++){
arr[l] = help[l];
}
return ans;
}
LL smallsum(int left , int right){
if(left >= right) return 0;
int mid = (left+right)/2;
return smallsum(left,mid)+smallsum(mid+1,right)+marge(left,right,mid);
}
int main() {
cin>>n;
for(int i=1;i<=n;i++) cin>>arr[i];
LL ans = smallsum(1,n);
//for(int i=1;i<=n;i++) cout<<arr[i]<<" ";
printf("%lld",ans);
}
// 64 位输出请用 printf("%lld")