考虑每个点的贡献,即为它与前面的数构成的逆序对个数+前面比它大的数
两个树状数组维护一下就可以了
#include<cstdio>
#include<cstring>
#define N 100005
#define LL long long
using namespace std;
int c[N],n; LL ans,val[N];
int Q1(int x){int ans=0;for(;x;x-=x&-x)ans+=c[x];return ans;}
LL Q2(int x){LL ans=0;for(;x;x-=x&-x)ans+=val[x];return ans;}
void Up1(int x,int v){for(;x<=n;x+=x&-x)c[x]+=v;}
void Up2(int x,int v){for(;x<=n;x+=x&-x)val[x]=(LL)val[x]+v;}
int main(){
while(~scanf("%d",&n)){
memset(c,0,sizeof(c));
memset(val,0,sizeof(val));
for(int i=1;i<=n;i++){
int x; scanf("%d",&x);
Up1(x,1) , Up2(x,x);
int num = i-Q1(x); LL sum = Q2(n)-Q2(x);
ans += (LL)num*x + sum;
}printf("%lld\n",ans);
}return 0;
}