#include <iostream>
using namespace std;
const
int
MAXN =
1000
;
int
A[MAXN], T[MAXN];
void
merge_sort(
int
*A,
int
x,
int
y,
int
*T) {
if
(y - x >
1
) {
int
m = x + (y - x) /
2
;
//划分
int
p = x, q = m, i = x;
merge_sort(A, x, m, T);
//递归求解
merge_sort(A, m, y, T);
//递归求解
while
(p < m || q < y) {
if
(q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++];
//从左半数组复制到临时空间
else
T[i++] = A[q++];
//从右半数组复制到临时空间
}
for
(i = x; i < y; ++i) A[i] = T[i];
//从辅助空间复制回A数组
}
}
int
main() {
int
n;
cin >> n;
for
(
int
i =
0
; i < n; ++i) cin >> A[i];
merge_sort(A,
0
, n, T);
for
(
int
i =
0
; i < n; ++i) cout << A[i] << endl;
return
0
;
}
#include <iostream>
using namespace std;
const
int
MAXN =
1000
;
int
A[MAXN], T[MAXN];
void
inverse_pair(
int
*A,
int
x,
int
y,
int
* cnt,
int
*T) {
if
(y - x >
1
) {
int
m = x + (y - x) /
2
;
//划分
int
p = x, q = m, i = x;
inverse_pair(A, x, m, cnt, T);
//递归求解
inverse_pair(A, m, y, cnt, T);
//递归求解
while
(p < m || q < y) {
if
(q >= y || (p < m && A[p] <= A[q])) T[i++] = A[p++];
//从左半数组复制到临时空间
else
{
T[i++] = A[q++];
//从右半数组复制到临时空间
*cnt += m-p;
//更新累加器
}
}
for
(i = x; i < y; ++i) A[i] = T[i];
//从辅助空间复制回A数组
}
}
int
main() {
int
n;
cin >> n;
for
(
int
i =
0
; i < n; ++i) cin >> A[i];
int
cnt =
0
;
inverse_pair(A,
0
, n, &cnt, T);
cout << cnt << endl;
return
0
;
}
#include<iostream>
#include<cstdio>
using namespace std;
#define max 100005
struct point{
int h;
int t;//统计该元素左边比他大的数的个数和该元素右边比他小的数的个数的总和
};
point l[max],r[max],c[max];
void Merge(point *a,int first,int last){//归并时,上数组的第一个元素与下数组的第一个元素相等,上数组的指针右移
int p,q,temp,mid;
mid=(first+last)/2;
temp=first;
p=first;
q=mid+1;
while(p<=mid&&q<=last){
if(a[p].h>a[q].h){
a[q].t+=mid+1-p;//上数组的第一个元素比下数组的第一个元素大,下数组的第一个元素前面有mid+1-p个数比他大
c[temp++]=a[q++];
}
else{
a[p].t+=q-1-mid;
//上数组的第一个元素与下数组的第一个元素相等或者上数组的第一个元素比下数组的第一个元素小
//注意:上数组的第一个元素与下数组的第一个元素相等时,也就是说下数组的第一个元素的前面的元素都比上数组的第一个元素小
//上数组的第一个元素后面有q-1-mid个数比他小
c[temp++]=a[p++];
}
}
while(q<=last){//下数组有剩余
c[temp++]=a[q++];
}
q--;
while(p<=mid){//上数组有剩余,也就是说下数组的所有元素都比上数组剩下的元素小,故上数组每个元素t加q-mid,也就是下数组的元素个数
a[p].t+=q-mid;
c[temp++]=a[p++];
}
int i=first;
for(;i<=last;i++){
a[i]=c[i];
}
}
void MergeSort(point *a,int first,int last){
if(first==last){
return;
}
int mid=(first+last)/2;
MergeSort(a,first,mid);
MergeSort(a,mid+1,last);
Merge(a,first,last);
}
int main(){
int n;
scanf("%d",&n);
//cout<<1<<endl;
int i=0;
for(;i<n;i++){
scanf("%d",&(l[i].h));
l[i].t=0;
}
MergeSort(l,0,n-1);
long long sum=0;//数的范围
for(i=0;i<n;i++){
long long s=l[i].t;
//cout<<"h: "<<l[i].h<<" "<<l[i].t<<endl;
sum+=(s+1)*s/2;//求和
}
cout<<sum<<endl;
return 0;
}
蓝桥杯——小朋友排队
- #include <iostream>
- #include <cstring>
- #include <string>
- #include <cstdio>
- #include <cmath>
- #include <map>
- #include <algorithm>
- using namespace std;
- typedef long long LL;
- LL count=0,n;
- struct Kids
- {
- LL h;
- LL num;
- }A[100005],T[100005];
- void merge_sort(int x, int y)
- {
- if(y-x<=1)return;
- int m=x+(y-x)/2;
- int p=x,q=m,i=x;
- merge_sort(x,m);
- merge_sort(m,y);
- while(p<m || q<y)
- {
- if(q>=y || (p<m && A[p].h<=A[q].h))
- {
- T[i++] = A[p++];
- T[i-1].num += q-m;
- }
- else
- {
- T[i++] = A[q++];
- T[i-1].num += m-p;
- }
- }
- for(int i=x;i<y;++i)A[i]=T[i];
- }
- int main()
- {
- cin>>n;
- for(int i=0;i<n;i++)
- {
- scanf("%I64d",&A[i].h);//cin>>A[i].h;
- A[i].num=0;
- }
- merge_sort(0,n);
- LL count=0;
- for(int i=0;i<n;i++)count+=(A[i].num+1)*A[i].num/2;
- cout<<count<<endl;
- return 0;
- }