poj 3928

用树状数组去维护前缀和,比a[i]小的个数

代码如下

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int a[20005],c[20005],d[20005];
int bit[100005];
int lowbit(int x)
{
    return x&(-x);
}
int sum(int i)
{
    int s=0;
    while(i>0) {
        s+=bit[i];
        i-=lowbit(i);
    }
    return s;
}
void Add(int i)
{
    while(i<=100000) {
        bit[i]+=1;
        i+=lowbit(i);
    }
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--) {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        memset(bit,0,sizeof(bit));
        for(int i=1;i<=n;i++) {
            c[i]=sum(a[i]-1);
            Add(a[i]);
        }
        memset(bit,0,sizeof(bit));
        for(int i=n;i>=1;i--) {
            d[i]=sum(a[i]-1);
            Add(a[i]);
        }
        long long ans=0;
        for(int i=2;i<n;i++) {
            ans+=c[i]*(n-i-d[i])+(i-1-c[i])*d[i];
        }
        printf("%lld\n",ans);
    }
}


猜你喜欢

转载自blog.csdn.net/qq_36651153/article/details/80037150