AcWing 1215. 小朋友排队
原题链接
中等
作者:
牛奶小柒Luke
,
2021-03-05 20:25:05
,
所有人可见
,
阅读 276
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 1000010;
int n;
int h[N],tr[N];
int sum[N];
int lowbit(int x){
return x & -x;
}
void add(int x,int v){
for(int i = x;i < N;i += lowbit(i)) tr[i] += v;
}
int query(int x){
int res = 0;
for(int i = x;i;i -=lowbit(i)) res += tr[i];
return res;
}
int main(){
scanf("%d",&n);
for(int i = 0;i < n;++i) scanf("%d",&h[i]),h[i]++;
//求每个数前面有多少个数比它大
for(int i = 0;i < n;++i){
sum[i] = query(N - 1) - query(h[i]);
add(h[i],1);
}
//每个数后面有多少个数比它小
memset(tr,0,sizeof tr);
for(int i = n - 1;i >= 0;--i){
sum[i] += query(h[i] - 1);
add(h[i],1);
}
LL res = 0;
//冒泡排序证明:交换了k1 + k2次
for(int i = 0;i < n;++i) res += (LL)sum[i] * (sum[i] + 1) / 2;
printf("%lld\n",res);
return 0;
}