树状数组_Ping pong

来源:互联网 发布:汽车资源软件下载 编辑:程序博客网 时间:2024/06/05 01:10

题意:给定n个数,a1~an。ai代表每个人的能力值。举办乒乓比赛一次需要三个人,要求中间的人(裁判)的能力值大于其左边的人且小于其右边的人。求一共能举办多少场比赛。

分析:用s1[i]表示第i个人的左边有s1[i]个人的能力值小于ai,用s2[i]表示第i个人的右边有s2[i]个人的能力值小于ai。则以第i个人为裁判可以举办(s1[i]*(n-i-s2[i])+(i-1-s1[i])*s2[i])场比赛。

AC代码

#include <cstdio>#include <cstring>using namespace std;#define lowbit(x) (x&-x)#define maxn 1000000typedef long long ll;ll n,a[maxn],c[maxn],d[maxn],s1[maxn],s2[maxn],x[maxn];ll sum(ll x){    ll res=0;    while(x>0)    {        res+=c[x];        x-=lowbit(x);    }    return res;}void add(ll x,ll d){    while(x<=100005)    {        c[x]+=d;        x+=lowbit(x);    }}int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(x,0,sizeof(x));        scanf("%lld",&n);        for(ll i=1;i<=n;i++)        {            scanf("%lld",&a[i]);        }        memset(c,0,sizeof(c));        for(ll i=1;i<=n;i++)        {            add(a[i],1);            s1[i]=sum(a[i]-1);        }        memset(c,0,sizeof(c));        for(ll i=n;i>=1;i--)        {            add(a[i],1);            s2[i]=sum(a[i]-1);        }        ll ans=0;        for(ll i=2;i<=n;i++)        {            ans+=s1[i]*(n-i-s2[i])+(i-s1[i]-1)*s2[i];        }        printf("%lld\n",ans);    }    return 0;}

原创粉丝点击