树状数组
t[N]存数出现的次数
#include<bits/stdc++.h>
using namespace std;
const int N=200020;
int n;
//把a[i]的数值化为叶节点,t[i]统计存的是数字个数
int a[N],t[N];
int gre[N],low[N];
void add(int x,int c){
for(int i=x;i<=n;i+=i&(-i)) t[i]+=c;
}
int sum(int x){
int res=0;
for(int i=x;i>=1;i-=i&(-i)) res+=t[i];
return res;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
//从左往右统计每个位置左边比i小/大的数
for(int i=1;i<=n;i++){
int y=a[i];
low[i]=sum(y-1);
gre[i]=sum(n)-sum(y);
add(y,1);
}
//清空树状数组
memset(t,0,sizeof t);
long long ans1=0,ans2=0;
//从右往左统计
for(int i=n;i>=1;i--){
int y=a[i];
ans1+=(long long)low[i]*sum(y-1);
ans2+=(long long)gre[i]*(sum(n)-sum(y));
add(y,1);
}
cout<<ans2<<" "<<ans1;
return 0;
}