Ping pong(hdu 2492 树状数组

题目链接: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;
}

 

posted @ 2019-08-14 20:29  -第4题-  阅读(233)  评论(0编辑  收藏  举报