HDU5147 Sequence II && BestCoder Round #23 1002

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5147

题思路:BestCoder官方题解:

要统计四元组的数量我们可以通过枚举c,然后统计区间[1,c-1]有多少二元组(a,b)满足a
   
    <
   b且
   
    Aa<Ab
   ,以及统计出区间[c+1,n]有多少d满足
   
    Ac<Ad
   ,根据乘法原理,把这两项乘起来就可以统计到答案里了.
然后我们来处理子问题:区间[1,c-1]内有多少二元组(a,b).那么我们可以枚举b,然后统计区间[1,b-1]内有多少a满足
   
    Aa<Ab
   ,那么这个可以通过用树状数组询问前缀和来实现.
时间复杂度是O(nlogn).
AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

typedef __int64 ll;
int a[50010];
int n;

int lowbit(int x)
{
    return x&(-x);
}

int getsum(int x)
{
    int sum=0;
    while(x)
    {
        sum+=a[x];
        x-=lowbit(x);
    }
    return sum;
}

void add(int x)
{
    while(x<=n)
    {
        a[x]++;
        x+=lowbit(x);
    }
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,m;
        ll pre=0,ans=0;
        memset(a,0,sizeof(a));
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            scanf("%d",&m);
            int t=getsum(m);
            int k=n-m-(i-t-1);//后面比m大的数字
            ans+=k*pre;
            pre+=t;
            add(m);
        }
        printf("%I64d\n",ans);
    }
    return 0;
}


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