HDU 2492 Ping pong

来源:互联网 发布:如何提高淘宝产品权重 编辑:程序博客网 时间:2024/06/08 00:43

题意:

一串数字  问  有几种这样的组合(x,y,z)使得x>y>z或x<y<z  y在x数字后面z在y后面  题目中每种数字是唯一的


思路:

对于一个数字  比如 f  它计算出的ans值为 

( beforef.lessthanf * afterf.biggerthanf )+( beforef.biggerthanf * afterf.lessthanf )

易知 beforef.biggerthanf = locationf - 1 - beforef.lessthanf 同理after

则式子可化简为 

( beforef.lessthanf * ( n - locationf - afterf.lessthanf ) )+( (locationf - 1 - beforef.lessthanf ) * afterf.lessthanf )

如果我们从小到大的处理每个数字  那么可知当前处理的数字是当前序列中最大的

则 afterf.lessthanf = nowallnumber - beforef.lessthanf

那么式子中将只出现一个未知数  也就是说我们只需要知道当前位置前有几个小于自己即可

因此用树状数组维护


代码:

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define N 20010#define lowbit(x) (x&(-x))int t,n;int a[N];__int64 ans;struct person{    int id,val;    bool operator<(const person fa) const    {        return val<fa.val;    }}f[N];void add(int x){    while(x<=n)    {        a[x]+=1;        x+=lowbit(x);    }}int sum(int x){    int res=0;    while(x)    {        res+=a[x];        x-=lowbit(x);    }    return res;}int main(){    int i,ls,lb,rs,rb,id;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        for(i=1;i<=n;i++)        {            f[i].id=i;            scanf("%d",&f[i].val);        }        sort(f+1,f+1+n);        memset(a,0,sizeof(a));        ans=0;        for(i=1;i<=n;i++)        {            id=f[i].id;            ls=sum(id);            lb=id-ls-1;            rs=sum(n)-ls;            rb=n-id-rs;            ans+=ls*rb;            ans+=lb*rs;            add(id);        }        printf("%I64d\n",ans);    }    return 0;}



0 0
原创粉丝点击