标签:
1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define max 100005 5 struct point{ 6 int h; 7 int t;//统计该元素左边比他大的数的个数和该元素右边比他小的数的个数的总和 8 }; 9 point l[max],r[max],c[max]; 10 void Merge(point *a,int first,int last){//归并时,上数组的第一个元素与下数组的第一个元素相等,上数组的指针右移 11 int p,q,temp,mid; 12 mid=(first+last)/2; 13 temp=first; 14 p=first; 15 q=mid+1; 16 while(p<=mid&&q<=last){ 17 if(a[p].h>a[q].h){ 18 a[q].t+=mid+1-p;//上数组的第一个元素比下数组的第一个元素大,下数组的第一个元素前面有mid+1-p个数比他大 19 c[temp++]=a[q++]; 20 } 21 else{ 22 a[p].t+=q-1-mid; 23 //上数组的第一个元素与下数组的第一个元素相等或者上数组的第一个元素比下数组的第一个元素小 24 //注意:上数组的第一个元素与下数组的第一个元素相等时,也就是说下数组的第一个元素的前面的元素都比上数组的第一个元素小 25 //上数组的第一个元素后面有q-1-mid个数比他小 26 c[temp++]=a[p++]; 27 } 28 } 29 while(q<=last){//下数组有剩余 30 c[temp++]=a[q++]; 31 } 32 q--; 33 while(p<=mid){//上数组有剩余,也就是说下数组的所有元素都比上数组剩下的元素小,故上数组每个元素t加q-mid,也就是下数组的元素个数 34 a[p].t+=q-mid; 35 c[temp++]=a[p++]; 36 } 37 int i=first; 38 for(;i<=last;i++){ 39 a[i]=c[i]; 40 } 41 } 42 void MergeSort(point *a,int first,int last){ 43 if(first==last){ 44 return; 45 } 46 int mid=(first+last)/2; 47 MergeSort(a,first,mid); 48 MergeSort(a,mid+1,last); 49 Merge(a,first,last); 50 } 51 int main(){ 52 int n; 53 scanf("%d",&n); 54 //cout<<1<<endl; 55 int i=0; 56 for(;i<n;i++){ 57 scanf("%d",&(l[i].h)); 58 l[i].t=0; 59 } 60 MergeSort(l,0,n-1); 61 long long sum=0;//数的范围 62 for(i=0;i<n;i++){ 63 long long s=l[i].t; 64 //cout<<"h: "<<l[i].h<<" "<<l[i].t<<endl; 65 sum+=(s+1)*s/2;//求和 66 } 67 cout<<sum<<endl; 68 return 0; 69 }
法二:
树状数组(学习中)。。。
标签:
原文地址:http://www.cnblogs.com/Deribs4/p/4279864.html