HDU - 2838

#include<bits/stdc++.h>
#define maxn 100100
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
/*--------------------*/
int n,a[maxn],cnt[maxn];
ll ans,total[maxn];
/*--------------------*/
int lowbit(int x)
{
    return x&(-x);
}
void add(int x)
{
    int tmp=x;
    while(x<=n)
    {
        cnt[x]++;
        total[x]+=tmp;
        x+=lowbit(x);
    }
}
ll sum1(int x )
{
    ll ret=0;
    while(x>0)
    {
        ret+=cnt[x];
        x-=lowbit(x);
    }
    return ret;
}
ll sum2(int x)
{
    ll ret=0;
    while(x>0)
    {
        ret+=total[x];
        x-=lowbit(x);
    }
    return ret;
}
/*--------------------*/
int main()
{
    while(cin>>n)
    {
        mem(cnt,0);
        mem(total,0);
        ans=0;
        for(int i=0;i<n;++i)
        {
            scanf("%d",&a[i]);
            add(a[i]);
            int t=sum1(a[i]);
            t=i-t+1;
            if(t!=0)
            {
                ans+=(ll)t*a[i]+sum2(n)-sum2(a[i]);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
} 

BIT+逆序数,BIT用来维护比当前数字小的个数和总和。

ans=sum(a[i]*个数+比当前数字小的总和)

posted @ 2018-11-26 10:08  JJSsnow  阅读(125)  评论(0编辑  收藏  举报