题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2492
树状数组分别从前往后 从后往前 找比当前位置的值 小的个数
贴一个别人写的树状数组的博客:https://www.cnblogs.com/acgoto/p/8583952.html 还是很详细的
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const LL N = 100005;
LL mp[N],n,tree[N],c[N],d[N];
LL lowbit(LL x)
{
return x&(-x);
}
LL sum(LL x)
{
LL ans = 0;
while(x>0)
{
ans+=tree[x];
x-=lowbit(x);
}
return ans;
}
void add(LL x)
{
while(x<N)
{
tree[x]+=1;
x+=lowbit(x);
}
}
int main()
{
int T,i,j;
scanf("%d",&T);
while(T--)
{
cin>>n;
for(i=0;i<n;i++)
{
scanf("%lld",&mp[i]);
}
for(i=0;i<N;i++)tree[i]=0;
for(i=0;i<n;i++)
{
c[i]=sum(mp[i]);add(mp[i]);//前面有多少人比它小
}
for(i=0;i<N;i++)tree[i]=0;
for(j=n-1;j>=0;j--)
{
d[j]=sum(mp[j]);add(mp[j]);//后面有多少人比它小
}
LL ans=0;
for(i=0;i<n;i++)
{
ans+=c[i]*(n-i-d[i]-1)+(i-c[i])*d[i];
// n-i-d[i]-1:后面比他大的个数 i-c[i]:前面比他大的个数
}
printf("%lld\n",ans);
}
return 0;
}