poj 3928 树状数组

/*
题意是要组成许多比赛,比赛的要求是,两个人比赛一个人作裁判,
裁判的能力值必须要在两个人之间,位置也是,问一共有多少种不同的比赛方式。
每个人的能力值各不相同。
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000;
int n,t;
__int64 c[maxn],lmin,lmax,rmin,rmax,ans;
struct node
{
    int x,id;
}p[maxn+2];
int cmp(node a,node b)
{
    return a.x<=b.x;
}
int lowbit(int i)
{
    return i&(-i);
}
void add(int i,__int64 d)
{
    while(i<=maxn)
    {
        c[i]+=d;
        i+=lowbit(i);
    }
}
__int64 sum(int i)
{
    __int64 ret=0;
    while(i)
    {
        ret+=c[i];
        i-=lowbit(i);
    }
    return ret;
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        ans=0;
        scanf("%d",&n);
        int i,j;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&p[i].x);
            p[i].id=i;
        }
        for(i=0;i<=maxn;i++) c[i]=0;
        sort(p+1,p+n+1,cmp);
        add(p[1].id,1);
        for(i=2;i<n;i++)
        {
            lmin=sum(p[i].id-1);
            lmax=p[i].id-1-lmin;
            rmin=sum(n)-sum(p[i].id);
            rmax=n-p[i].id-rmin;
            ans+=(lmin*rmax+rmin*lmax);  add(p[i].id,1);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}
/*
3
5
1 3 2 4 5
*/

你可能感兴趣的:(poj 3928 树状数组)